- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个连接到 Spring-MVC 服务器的 Java 应用程序,使用 Spring-Security 进行身份验证/授权。登录部分有效,我在 Java 应用程序中得到了一个 JSESSIONID,但是当我向 protected 资源发出请求时,它失败了,Spring-Security 无法找到任何登录的用户。我在这里做错了什么?
安全-applicationContext.xml:
<security:http pattern="/resources/**" security="none"/>
<security:http create-session="ifRequired" use-expressions="true" auto-config="false" disable-url-rewriting="true">
<security:form-login login-page="/login" login-processing-url="/j_spring_security_check"
default-target-url="/dashboard" always-use-default-target="false"
authentication-failure-url="/denied"/>
<security:remember-me key="_spring_security_remember_me" user-service-ref="userDetailsService"
token-validity-seconds="1209600" data-source-ref="dataSource"/>
<security:logout delete-cookies="JSESSIONID" invalidate-session="true" logout-url="/j_spring_security_logout"/>
<!--<security:intercept-url pattern="/**" requires-channel="https"/>-->
<security:port-mappings>
<security:port-mapping http="8080" https="8443"/>
</security:port-mappings>
<security:logout logout-url="/logout" logout-success-url="/" success-handler-ref="myLogoutHandler"/>
<security:session-management session-fixation-protection="migrateSession">
<security:concurrency-control session-registry-ref="sessionRegistry" max-sessions="5" expired-url="/login"/>
</security:session-management>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="restaurantauthenticationprovider"/>
<security:authentication-provider ref="userauthenticationprovider"/>
</security:authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11"/>
</beans:bean>
<beans:bean id="restaurantauthenticationprovider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="LoginServiceImpl"/>
<beans:property name="passwordEncoder" ref="encoder"/>
</beans:bean>
<beans:bean id="userauthenticationprovider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="UserLoginServiceImpl"/>
<beans:property name="passwordEncoder" ref="encoder"/>
</beans:bean>
由于我有 2 个表要检查从中登录,因此我有 2 个 DAOAuthenticationProvider。
UserLoginServiceImpl:
@Transactional
@Service("loginuserDetailsService")
public class UserLoginServiceImpl implements UserDetailsService {
@Autowired
private PersonDAO personDAO;
@Autowired
private UserAssembler userAssembler;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,DataAccessException {
System.out.println("Username is "+username);
Person person = this.personDAO.findPersonByUserName(username.toLowerCase());
if(person == null) { throw new UsernameNotFoundException("Wrong username or password");}
return userAssembler.buildUserFromUserEntity(person);
}
}
汇编器:
@Service("userassembler")
@Transactional
public class UserAssembler {
@Transactional
User buildUserFromUserEntity(Person userEntity){
System.out.println("We are in Userassembler"+userEntity.getEmail());
String username = userEntity.getUsername().toLowerCase();
String password = userEntity.getPassword();
boolean enabled = userEntity.isEnabled();
boolean accountNonExpired = userEntity.isAccountNonExpired();
boolean credentialsNonExpired = userEntity.isCredentialsNonExpired();
boolean accountNonLocked = userEntity.isAccountNonLocked();
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new User(username,password,enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,authorities);
}
}
上面是配置,现在我将放置失败的其余代码:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Log.d("Username is ", username);
String jsessionid = rest.execute("http://192.168.178.60:8080/j_spring_security_check", HttpMethod.POST,
new RequestCallback() {
@Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
request.getBody().write(("j_username=" + username + "&j_password=" + password).getBytes());
}
}, new ResponseExtractor<String>() {
@Override
public String extractData(ClientHttpResponse response) throws IOException {
List<String> cookies = response.getHeaders().get("Cookie");
if (cookies == null) {
cookies = response.getHeaders().get("Set-Cookie");
}
String cookie = cookies.get(cookies.size() - 1);
System.out.println("Cookie is " + cookie);
// The method below gets me which user is logged in, and I always get null for Controller method.
reply = rest.getForObject(
"http://192.168.178.60:8080/dashboard", String.class);
int start = cookie.indexOf('=');
int end = cookie.indexOf(';');
return cookie.substring(start + 1, end);
}
});
}
});
thread.start();
更新最后,有效的代码:
//我从服务器获取cookie,我为每个请求手动设置cookie,cookie是一个静态 volatile 字符串。
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
HttpEntity requestEntity = new HttpEntity(null, requestHeaders);
ResponseEntity rssResponse = rest.exchange(
"http://192.168.178.60:8080/dashboard",
HttpMethod.GET,
requestEntity,
String.class);
String abc = (String) rssResponse.getBody();
最佳答案
Spring 的 RestTemplate 默认情况下不跟踪 cookie。这可以确保您不会意外地从一个用户代表另一用户传递 cookie(即 JSESSIONID)(即考虑在许多用户使用相同 RestTemplate 的服务器上使用 RestTemplate)。
如果您想这样做,您可以使用如下方式进行配置:
RestTemplate rest = new RestTemplate();
// initialize the RequestFactory to allow cookies
HttpClient httpClient = HttpClientBuilder.create().build();
ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
rest.setRequestFactory(factory);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("username", "user");
map.add("password", "password");
String result = rest.postForObject("http://localhost:8080/login", map, String.class);
String hello = rest.postForObject("http://localhost:8080/", map, String.class);
assertThat(hello).isEqualTo("Hello");
要使用此代码,您需要确保类路径上有 httpclient。例如,如果您使用 Maven,则 pom.xml 中可能包含以下内容:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5</version>
</dependency>
显然,您需要确保包含适用于您的依赖项的 httpclient 版本。
关于java - Spring 安全 : Not acknowledging cookie set in RestTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31343508/
我编写了以下代码来测试同步 RestTemplate 和 AsyncRestTemplate 的性能。我只是在 POSTMAN 上手动运行了几次。 我们只是将 10 个引用传递给 GET 调用,以便我
这种方式创建RestTemplate有什么区别 RestTemplate restTemplate = restTemplateBuilder .setConnectT
这个问题已经有答案了: IllegalArgumentException: Not enough variable values available with RestTemplate? (2 个回答
这是我的应用程序的主类 @SpringBootApplication (scanBasePackages = { "com.xyz.*" }) @EnableAsync @EnableAspectJA
我当前的代码: RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new
我将开发一个简单的 Spring MVC Web 应用程序,它将使用 Heroku 上的远程 RESTful 服务。 我希望 MVC Web 应用程序根据 Controller 调用 REST 服务。
项目场景: Spring 的 RestTemplate 是一个健壮的、流行的基于 Java 的 Http客户端。 RestTemplate实现request param参数传送,如果如下所示,直接传一
我想通过 RestTemplate 发送请求。但是我的网址有大括号('{','}'),因此我有异常(exception):“没有足够的变量值可用于扩展......”。 我尝试通过 uri UriCom
有一个 RestFull 方法返回一个菜单对象列表 public ResponseEntity> getMenus() { .. } 但我不知道如何从 RestTemplate 中获取它们,从 Res
摘要: RestTemplate与REST资源交互的方法涵盖了HTTP请求方法,包括get, post, put, delete。 本文分享自华为云社区《Springboot RestTemplate
我有一个 springboot 休息服务 A 使用 restTemplate 调用休息服务 B。休息服务 A 的 restTemplate bean 创建如下,超时设置如下面的代码片段所示。 @Bea
我有一个 @Service有几种方法,每种方法使用不同的 web api。每个调用都应该有一个自定义的读取超时。 拥有一个 RestTemplate 实例并在每个方法中通过工厂更改超时是否是线程安全的
这是我的休息模板配置, @Bean @Qualifier("myRestService") public RestTemplate createRestTemplate(@Va
是否可以使用 RestTemplateBuilder 创建仅带有不记名 header 和 token 的 RestTemplate 实例? 我知道我可以使用 RestTemplate 交换并在 Htt
我正在尝试对请求正文执行 DELETE,但我不断收到 400(错误请求)错误。当我在 swagger/postman 中这样做时,它成功地删除了记录。但是从 Java 代码我不能这样做 外部 API
我需要创建 RestTemplate 请求,它将发送图像以通过 PHP 应用程序上传。 我的代码是: Resource resource = new FileSystemResource("/User
我正在使用 swagger codegen ( on this Zoura swagger ) 创建 Java/rest 模板客户端。我正在使用 swagger Gradle 插件: id "org.
我有Restful API,当找不到某个项目时会响应404错误,但是根据未找到该项目的原因(未知,不可用等),会有不同的消息,可以使用Spring MVC通过以下方式完成: response.send
我正在使用 Spring 中的 RestTemplate 来查询搜索服务。我在进行正确的序列化方面遇到了一些困难。如果我使用此方法,restTemplate 将返回一个列表。我不明白如何传递参数化类型
我们有这样的代码,它使用 OData 来指定资源(为简单起见,在此处使用公司代码进行硬编码): String uri = "[my_endpoint]/companyprofiles.read?$fi
我是一名优秀的程序员,十分优秀!