2014-03-04 151 views
6

我想实现沿this guide春季安全与rememberMe和REST的API

基本流线的API是:

  • 移动应用程序嵌入Web视图用户登录(正常的Web应用安全)
  • 在登录时,Web应用程序返回一个令牌
  • 移动应用程序安全cookie使用该令牌在将来的所有API请求

所以我试图通过登录表单来保证我的webapp允许正常的登录流程(通过Spring Security),然后根据请求标头中传递的令牌验证对/ api/**的所有请求。

我本来开始通过具有两个网络CONFIGS实现这一点 - 一个用于正常的web应用安全:

@Override protected void configure(HttpSecurity http) throws Exception { 
     http 
      .csrf() 
       .disable() 
      .authorizeRequests() 
       .antMatchers("/resources/**").permitAll() 
       .antMatchers("/sign-in").permitAll() 
       .antMatchers("/success").authenticated() 
       .anyRequest().authenticated() 
       .and() 
      .formLogin() 
       .loginPage("/") 
       .loginProcessingUrl("/loginprocess") 
       .failureUrl("/sign-in?loginFailure=true") 
       .permitAll(); 
    } 

以上只是定义了标准的Spring Security认证(自定义的UserDetailsS​​ervice从DB获得的UserDetails)和登录验证他和成功页面。

然后另一个(两个文件只是为了清楚/便于阅读)的API认证:

@Override protected void configure(HttpSecurity http) throws Exception { 
    http 
     .antMatcher("/api/**") 
     .csrf() 
      .disable() 
     .authorizeRequests().anyRequest().authenticated().and() 
     .addFilterBefore(authenticationTokenFilter(), BasicAuthenticationFilter.class) 
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() 
      .exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint()); 
} 

上面有一个AUTH预过滤器从请求抓住相关HTTP标头(令牌等)并将它们添加到安全上下文 - 自定义身份验证提供程序然后验证令牌/用户详细信息。

所有的好 - 但是,它感觉就像我重新发明了一堆东西。看过Spring Security的RememberMe功能后,看起来他们已经处理了很多事情 - 在登录时它会返回一个带有令牌的cookie,然后该令牌可用于未来请求的自动登录。从the java docs

<bean id="rememberMeFilter" class= 
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter"> 
    <property name="rememberMeServices" ref="rememberMeServices"/> 
    <property name="authenticationManager" ref="theAuthenticationManager" /> 
</bean> 

<bean id="rememberMeServices" class= 
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices"> 
    <property name="userDetailsService" ref="myUserDetailsService"/> 
    <property name="key" value="springRocks"/> 
</bean> 

<bean id="rememberMeAuthenticationProvider" class= 
"org.springframework.security.authentication.rememberme.RememberMeAuthenticationProvider"> 
    <property name="key" value="springRocks"/> 
</bean> 

唯一的问题是,我想包括在报头参数,可以不是一个cookie将来的请求令牌。我已经查看了上述类的源代码,并且TokenBasedRememberMeServices类autoLogin()方法明确检查了Cookie。该代码还使用MD5作为散列的默认值。

我的问题是:

  1. 是否有一个标准的Spring类,它可以从请求头,而不是饼干
  2. 处理了rememberMe 功能是否有使用更好的散列算法MD5比什么? (可以很容易地切换而不重写?)。或者,甚至更好 - 我已经穿过KeyBasedPersistenceTokenService 看起来像 更好的令牌生成服务(SHA512 &附加密钥信息), 是否有任何使用它创建/验证安全令牌的良好示例。

我宁愿不必扩展所有这些类,因为一堆核心的东西会是一样的,而且似乎矫枉过正,不得不扩展它们来改变标记的来源和哈希算法。

回答

7

好的,看了一下,似乎没有实现请求头的RememberMe功能的核心类 - 但是,通过Spring Security阅读我的源代码,实际上很容易扩展上述类查看请求头。

细节都在这里:http://automateddeveloper.blogspot.co.uk/2014/03/securing-your-mobile-api-spring-security.html但基本上只是使用RememberMe作为正常的,但然后扩展TokenBasedRememberMeServices并重写extractCookie方法只是从标头抓取标记而不是cookie(可能有点hacky,扩展方法所谓extractCookie来抓取请求标题,但它的工作原理)

+0

非常有帮助我正在考虑采用相同的方法。你有没有运气利用类似于KeyBasedPersistenceTokenService的东西来生成令牌? – mjj1409

+0

不,我没有使用它 - 我只是坚持使用标准的RememberMe token生成器(因为它被认为足以在浏览器中记住我的功能,所以我决定不投资改变它。 – rhinds