Spring Security RememberMe& RESTful API

时间:2014-03-04 21:55:04

标签: spring rest authentication spring-security

我正在尝试按this guide

的方式实现API

基本流程是:

  • 移动应用程序嵌入了用户登录的Web视图(正常的Web应用程序安全性)
  • 登录时,webapp会返回带有令牌的安全Cookie
  • 移动应用在所有未来的API请求中使用令牌

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

我最初通过两个网络配置开始实现这一点 - 一个用于正常的webapp安全性:

@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安全认证(自定义userDetailsS​​ervice以从DB获取用户详细信息)并验证登录和成功页面。

然后另一个(两个文件只是为了清晰/易于阅读)进行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());
}

上面有一个pre-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. 是否有可以处理RememberMe的标准Spring类 来自请求标头而非Cookie的功能
  2. 有没有比MD5更好的哈希算法? (是真的吗 容易切换而不会超越?)。或者,甚至更好 - 我来了 横跨KeyBasedPersistenceTokenService看起来像一个 更好的令牌生成服务(SHA512和其他密钥信息), 是否有任何使用它来创建/验证的好例子 安全令牌。
  3. 我宁愿不必扩展所有这些类,因为一堆核心内容是相同的,并且只是为了更改令牌源和散列算法而扩展它们似乎有些过分。

1 个答案:

答案 0 :(得分:7)

好的,看了一下,似乎没有为请求标头实现RememberMe功能的核心类 - 但是,阅读Spring Security记住我的源代码,实际上很容易将上面的类扩展到查看请求标题。

详细信息都在这里:http://automateddeveloper.blogspot.co.uk/2014/03/securing-your-mobile-api-spring-security.html但基本上只是正常使用RememberMe,但是然后扩展TokenBasedRememberMeServices并覆盖extractCookie方法,只是从标题而不是cookie中抓取令牌(可能有点hacky,扩展一个名为extractCookie的方法来获取请求标题,但它可以工作)