Spring Security令牌认证 - RESTful JSON服务

时间:2014-06-10 20:52:33

标签: spring-mvc spring-security restful-authentication

我希望将Spring Security用于Spring MVC应用程序,该应用程序将严格地作为JSON Web服务。我做了一些研究并阅读了一些文章,但还没有找到任何完整的内容。我希望应用程序完全无状态并使用基于令牌的身份验证。我不希望Spring MVC应用程序有任何形式,或使用表单进行身份验证。它应该严格地接受JSON中的请求和数据,并返回JSON响应。

将会有一个Angular JS客户端应用程序,它需要发送用户名和密码,并从应用程序中获取要在顺序请求中使用的令牌。在某些时候,也可能有Android客户端访问此Web服务。

我假设Spring Security在内部将令牌映射到用户会话,这意味着它知道令牌XXXXXXXXXXXX是管理员用户Bob而令牌AAAAAAAAAA是标准用户Joe。但是我对Spring Security没有多少经验,所以我不知道这一切是如何结合在一起的。我仍然希望能够在控制器和服务方法上使用安全注释。

有没有办法在Spring Security中实现这一目标?

这个问题似乎是一个很好的起点,但我不确定这会像我设想的那样有效RESTful Authentication via Spring

3 个答案:

答案 0 :(得分:18)

这是一个以Spring-Rest-Boilerplate开头的好地方。

  1. 您第一次使用http基本身份验证和 然后登录(发送用户名/密码),这将返回令牌。
  2. 在后续请求中,您将使用此令牌进行身份验证。
  3. 您必须在链中添加一个过滤器来执行此操作 基于令牌的身份验证。
  4. 您必须为其提供令牌格式和加密。理想情况下,您还需要保留令牌的到期时间,到期时间以及用户名可能是令牌的一部分。使用加密算法加密哈希函数(如MD5)并获取整个令牌的哈希值。< / p>

    编辑:正如MaciejStępyra指出的那样,MD5似乎已被破坏,建议使用强大的哈希函数,如SHA-256。

    默认情况下,Spring安全性会将您重定向到登录页面,但这在REST的情况下没有意义,因此在配置中使用自定义AuthenticationEntryPoint(参考示例github代码)。

    我正在使用这种格式代码: 的 token:username:hash:expiry

    散列= MD5(用户名+ magickey)

    期满= CURRENT_TIMESTAMP + mins_to_expiry

     <security:http realm="Protected API" use-expressions="true" auto-config="false" create-session="always" entry-point-ref="**CustomAuthenticationEntryPoint**">
            <security:custom-filter ref="**authenticationTokenProcessingFilter**" position="PRE_AUTH_FILTER" />
            <security:intercept-url pattern="/**" access="isAuthenticated()" />
     </security:http>
    

    注意:感谢 dhavaln 代码。我用它作为参考并开发了类似的东西。

答案 1 :(得分:1)

“我希望应用程序完全无状态”

我会重新考虑你要做的事情。您无法找到解决方案的好例子是有原因的:您根本无法拥有既无状态又安全的应用程序。此外,如果你在某处存储令牌,那么你就不是无国籍人。即使您没有存储令牌(比如使用JWT对其进行编码),如果用户将在Web浏览器中访问它,您必须防止CSRF攻击。如果你选择了自己的路线,那么期望编写大量的自定义安全代码(这是一件坏事)。请参阅此处的讨论:https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii

答案 2 :(得分:1)

在我的情况下,我发现使用在多个tomcat节点之间共享SecurityContext的实现替换org.springframework.security.web.context.SecurityContextRepository中的org.springframework.security.web.context.SecurityContextPersistenceFilter更容易。客户端不断发送类似jsessionid的令牌,但我可以进行简单的循环负载平衡,而不必担心会话复制。