Spring Security RememberMe和RESTful API

rhi*_*nds 6 authentication rest spring spring-security

我正在尝试按照本指南的说明实现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();
    }
Run Code Online (Sandbox Code Playgroud)

上面只定义了标准的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());
}
Run Code Online (Sandbox Code Playgroud)

上面有一个pre-auth过滤器,它从请求中获取相关的HTTP头(令牌等)并将它们添加到安全上下文中 - 然后自定义身份验证提供程序验证令牌/用户详细信息.

一切都很好 - 然而,感觉我正在重新发明一堆东西.看过Spring Security的RememberMe功能后,看起来他们已经处理了很多这样的事情 - 在登录时它返回一个带有令牌的cookie,然后可以用于在将来的请求中自动登录.来自java文档:

<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>
Run Code Online (Sandbox Code Playgroud)

唯一的问题是我想在未来的请求中包含令牌作为标题参数,而不是cookie.我查看了上述类的源代码,并且TokenBasedRememberMeServices类autoLogin()方法显式检查了cookie.该代码还使用MD5作为散列的默认值.

我的问题是:

  1. 是否有一个标准的Spring类可以处理来自请求头而不是cookie的RememberMe功能
  2. 有没有什么比MD5使用更好的哈希算法?(可以轻松切换而不会覆盖?).或者,甚至更好 - 我遇到了KeyBasedPersistenceTokenService,它看起来像一个更好的令牌生成服务(SHA512和其他密钥信息),是否有任何使用它来创建/验证安全令牌的好例子.

我宁愿不必扩展所有这些类,因为一堆核心内容是相同的,并且似乎有点过分,只需要扩展它们来改变令牌的来源和散列算法.

rhi*_*nds 7

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

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