Spring Security RememberMe & RESTful API

Posted

技术标签:

【中文标题】Spring Security RememberMe & RESTful API【英文标题】: 【发布时间】:2014-04-06 16:42:23 【问题描述】:

我正在尝试按照this guide 的方式实现 API

基本流程是:

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

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

我最初是通过两个 web 配置开始实现这一点的 - 一个用于正常的 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获取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());

上面有一个预授权过滤器,它从请求(令牌等)中获取相关的 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 作为哈希的默认值。

我的问题是:

    是否有可以处理 RememberMe 的标准 Spring 类 来自请求标头而不是 cookie 的功能 有没有比 MD5 使用更好的散列算法? (是真的吗 无需覆盖即可轻松切换?)。或者,甚至更好——我来了 穿过KeyBasedPersistenceTokenService,看起来像一个 更好的令牌生成服务(SHA512 和附加密钥信息), 有没有什么好的例子可以使用它来创建/验证 安全令牌。

我宁愿不必扩展所有这些类,因为一堆核心内容是相同的,而且为了更改令牌的来源和散列算法而必须扩展它们似乎有点矫枉过正。

【问题讨论】:

对 httpBasic() 方法有任何想法吗? 【参考方案1】:

好的,环顾四周,似乎没有核心类实现了请求标头的 RememberMe 功能 - 但是,通过阅读 Spring Security 记住我源代码,将上述类扩展为实际上非常简单查看请求头。

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

【讨论】:

非常有帮助 我正在考虑采用相同的方法。你有没有运气利用类似于 KeyBasedPersistenceTokenService 的东西来生成令牌? 不,我没有考虑过使用它——我只是坚持使用标准的 RememberMe 令牌生成(因为它被认为足以在浏览器中实现记住我的功能,所以我决定不投资更改它.

以上是关于Spring Security RememberMe & RESTful API的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security:2.4 Getting Spring Security

没有 JSP 的 Spring Security /j_spring_security_check

Spring-Security

Spring Security 登录错误:HTTP 状态 404 - /j_spring_security_check

未调用 Spring Security j_spring_security_check

Spring Security入门(3-7)Spring Security处理页面的ajax请求