【发布时间】:2015-08-19 16:39:43
【问题描述】:
我尝试使用 cookie 实现身份验证(针对我的 android 客户端应用程序),基于这篇文章 -http://automateddeveloper.blogspot.co.uk/2014/03/securing-your-mobile-api-spring-security.html
安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final static String TOKEN_STRING = "my_token";
private final static String COOKIE_STRING = "my_cookie";
@Autowired
private UserDetailsService userSvc;
@Autowired
private MyTokenBasedRememberMeService tokenSvc;
@Autowired
private RememberMeAuthenticationProvider rememberMeProvider;
@Autowired
private MyAuthSuccessHandler authSuccess;
@Autowired
private MyAuthFailureHandler authFailure;
@Autowired
private MyLogoutSuccessHandler logoutSuccess;
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userSvc)
.passwordEncoder(passwordEncoder());
auth.authenticationProvider(rememberMeProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/register").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/loginendpoint")
.successHandler(authSuccess)
.failureHandler(authFailure).and()
.logout()
.logoutUrl("/logout")
.logoutSuccess(logoutSuccess)
.deleteCookies(COOKIE_STRING).and()
.rememberMe()
.rememberMeServices(tokenSvc).and()
.csrf()
.disable()
.addFilterBefore(rememberMeAuthenticationFilter(), BasicAuthenticationFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public RememberMeAuthenticationFilter rememberMeAuthenticationFilter() throws Exception {
return new RememberMeAuthenticationFilter(authenticationManager(), tokenBasedRememberMeService());
}
@Bean
public RememberMeAuthenticationProvider rememberMeAuthenticationProvider() {
return new RememberMeAuthenticationProvider(TOKEN_STRING);
}
@Bean
public MyTokenBasedRememberMeService tokenBasedRememberMeService() {
MyTokenBasedRememberMeService service = new MyTokenBasedRememberMeService(TOKEN_STRING,
userSvc);
service.setAlwaysRemember(true);
service.setCookieName(COOKIE_STRING);
return service;
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
MyTokenBasedRememberMeService:
public class MyTokenBasedRememberMeService extends TokenBasedRememberMeServices {
private final static String TOKEN_STRING = "my_token";
public MyTokenBasedRememberMeService(String key, UserDetailsService userDetailsService) {
super(key, userDetailsService);
}
@Override
protected String extractRememberMeCookie(HttpServletRequest request) {
String token = request.getHeader(TOKEN_STRING);
if ((token == null) || (token.length() == 0)) {
return "";
}
return token;
}
}
不幸的是,在成功登录后,我的 cookie 在客户端是空的:
Set-Cookie: my_cookie=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
怎么了?
-------编辑 1-------
如果您直接在浏览器中登录,您不会收到任何 cookie(例如在开发工具中)?
我使用邮递员对其进行了测试,但我只收到了 JSESSIONID cookie(没有 my_cookie)。
另外,您是否使用自定义登录控制器方法? (例如,您的用户控制器是否明确地对用户进行身份验证?)
是的,我正在使用自定义登录控制器方法,但我是 Spring Security 的新手,如果可以在没有自定义控制器的情况下完成,我将不胜感激任何解释。我的控制器负责对用户进行身份验证。
如果您没有使用 spring-security 来处理身份验证,那么我怀疑您可能必须自己显式设置 cookie 等
不,我只使用弹簧安全性。至少我是这么认为的...... :)
UserController 登录方法是做什么的?
我更新了我的代码。
-------编辑 2-------
根据@rhinds 的建议和 spring 文档,我纠正了一些事情(上面的代码已更新)。现在我可以登录loginendpoint,登录后我得到my_cookie。但我有相关的问题:
- 成功登录后,我收到一个 cookie 作为响应。如果令牌是在服务器端自动添加的,我必须手动添加令牌(客户端)以进一步请求?
- 注销怎么办? “Spring”如何知道必须注销哪个用户?
- 令牌到期日期如何?默认是2周,然后呢?我可以设置令牌永不过期吗?
对于将做类似事情的人,我建议也看看这篇很棒的文章 - https://dzone.com/articles/secure-rest-services-using :)
【问题讨论】:
-
如果您直接在浏览器中登录,您不会收到任何 cookie(例如在开发工具中)?
-
另外,您使用的是自定义登录控制器方法吗? (例如,您的用户控制器是否显式地对用户进行身份验证?) - 如果您没有使用 spring-security 来处理身份验证,那么我怀疑您可能必须自己显式设置 cookie 等。 (如果没有,UserController 登录方法是做什么的?)
-
@rhinds,请看我更新的帖子。
-
我现在已经更新了我的答案
标签: spring cookies spring-security spring-boot