Bak*_*123 4 cookies spring spring-security spring-boot
根据本文,我尝试使用Cookie来实现针对我的android客户端应用程序的身份验证-http: //automateddeveloper.blogspot.co.uk/2014/03/securing-your-mobile-api-spring-security.html
SecurityConfig:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,成功登录后,我的cookie在客户端是空的:
Set-Cookie: my_cookie=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
Run Code Online (Sandbox Code Playgroud)
怎么了?
-------编辑1 -------
如果直接在浏览器中登录,就不会得到cookie(例如在开发工具中)?
我使用邮递员对其进行了测试,但仅收到JSESSIONID cookie(没有my_cookie)。
另外,您是否正在使用自定义登录控制器方法?(例如,您的usercontroller是否明确认证用户?)
是的,我使用的是自定义登录控制器方法,但是我在Spring Security中是新手,如果可以在没有自定义控制器的情况下完成操作,我将不胜感激。我的控制器负责用户的身份验证。
如果您没有使用spring-security来处理身份验证,那么我怀疑您可能必须自己显式设置cookie等
不,我只使用Spring Security。至少我是这么认为的... :)
UserController登录方法在做什么?
我更新了我的代码。
-------编辑2 -------
根据@rhinds的建议和spring文档,我更正了一些事情(以上代码已更新)。现在,我可以登录loginendpoint
并登录后得到my_cookie
。但是我有相关的问题:
对于将要执行类似操作的人,我也建议您阅读这篇出色的文章-https ://dzone.com/articles/secure-rest-services-using :)
好的,所以最好的起点是远离自定义的spring控制器进行登录,而仅将其委托给spring安全-这些文档将为您提供有关如何入门的很好的概述- 参见此处开始
在链接的文章中,如果您查看配置代码:
@Override protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/sign-up").permitAll()
.antMatchers("/sign-in").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/loginprocess")
.failureUrl("/mobile/app/sign-in?loginFailure=true")
.permitAll().and()
.rememberMe().rememberMeServices(tokenBasedRememberMeService);
}
Run Code Online (Sandbox Code Playgroud)
.formLogin()
呼叫下的部分告诉Spring-security哪个端点监听登录尝试-例如,如果我具有此配置并连接POST
到该端点,/loginprocess
则Spring-security将拦截它并使用身份验证管理器来处理提交的表单(期望用户名)和密码字段等)。
下一个重要的方面是您userDetailsService
和身份验证管理器的接线:
@Override protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsServiceImpl)
.passwordEncoder(bCryptPasswordEncoder());
auth.authenticationProvider(rememberMeAuthenticationProvider);
}
Run Code Online (Sandbox Code Playgroud)
在给定的登录尝试下,这为spring-security提供了一种尝试加载用户对象的方法-只要您实现了类,UserDetailsService
则spring security应该具有所需的一切。
假设一切正确,那么您应该能够删除自定义登录控制器方法,定义一个loginProcessingUrl
,然后再对其POST
进行定义,spring-security应该加入并(尝试)对其进行处理。
花费一些时间让spring-security配置工作并处理简单的登录情况可能是值得的,一旦将所有这些都委派给了spring-security机械,应该更容易地更新配置以将其记住。
回应编辑2
我假设您是根据此处的一般方法遵循链接文章中的实现详细信息的:http : //automateddeveloper.blogspot.co.uk/2014/03/securing-your-api-for-mobile-access.html (您在操作中已链接到的实施细节的说明)
- 成功登录后,我收到一个cookie作为响应。为了进一步请求,我必须手动添加令牌(客户端)(如果令牌是在服务器端自动添加的)?
因此,假设您正在登录,然后从移动应用程序发出API请求-根据文章,您需要在应用程序中使用一个Webview来允许用户登录,一旦他们这样做,WebView将接收到登录响应,包括cookie。此时,您所关心的就是从cookie中提取令牌-之后,就不需要cookie。在您的应用程序中,您可以按自己的喜好保留令牌,只需添加并确保在您从该应用程序发出的每个API请求中都提供该令牌-本文中的RememberMe实现从API请求标头中提取令牌并验证用户身份。
- 那么注销呢?“ Spring”如何知道必须注销哪个用户?
不会-配置已设置为无状态,例如,它不跟踪已登录的用户,即通过有效cookie的存在(或在API请求的情况下,存在令牌的情况下记录的日志)提取)-例如在无状态模式下,将检查对应用程序的每个请求,以查看其是否已通过身份验证
- 令牌的到期日期呢?默认值为2周,那又如何?我可以设置为令牌永不过期吗?
再次,假设您遵循上面链接中描述的模式,这没关系,因为我们在第一次登录时就使用该cookie,之后您的应用程序将具有一个用于记住身份的“记住我”令牌,因此该cookie实际上就是从这一点上丢弃。
归档时间: |
|
查看次数: |
14743 次 |
最近记录: |