我使用Spring Security来保护使用Spring构建的RESTful Web服务,但在过去,请求使用了身份验证标头进行身份验证。现在,当用户的凭据在cookie中时,我需要保护这样的应用程序。
我正在尝试找出从cookie中提取用户信息并将其放入身份验证标头的最佳方法,或者理想情况下只使用Cookie中loadUserByUsername
方法的值{ {1}} bean。
到目前为止,我已经提出了一些关于如何做到这一点的想法:
我可以添加UserDetailsService
来使用Cookie为请求添加身份验证标头。但是,并非所有请求都需要身份验证,因此如果我这样做,我会将其应用于某些方法或请求映射而不是其他请求,我不知道如何执行此操作。
我可以在this tutorial中显示HandlerInterceptor
。在那个教程中,虽然我真的不明白他为什么AuthenticationEntryPoint
作为response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );
方法的主体。在我的用例中,我是否会在那里使用cookie添加身份验证标头?
我可以在所有控制器方法的第一行使用自定义方法执行安全检查。看起来当你遵循Spring Security的理想路径时,它是一个非常好的解决方案。我需要做的似乎是偏离这一点,但我的要求实际上非常简单。也许我会以简单的老式方式做得更好?
我不知道/没有想到的更好的主意!
感谢您的帮助和想法!
答案 0 :(得分:3)
如果我的要求正确,最简单的方法是使用Spring Security的Pre-Authentication Framework Classes来实现所需的身份验证机制。
通常,这些类旨在支持场景,其中身份验证机制由某个外部系统提供,该系统确保http请求包含可由任何webapp使用的某种身份验证信息。在您的情况下,身份验证信息似乎位于可用于识别用户的cookie中。
假设您已经有一个UserDetailsService
实现来按名称查找用户,您可以非常轻松地实现您的要求:
1)创建实现抽象方法AbstractPreAuthenticatedProcessingFilter
的{{1}}的子类,以从cookie中提取主体(用户名)。如果请求中没有凭据,还有另一种抽象方法(getPreAuthenticatedPrincipal(HttpServletRequest)
)可能只返回null。然后,在抽象超类中实现的逻辑会创建一个包含提取的主体的身份验证令牌,并将其提交给身份验证管理器。
2)创建一个类型为getPreAuthenticatedCredentials()
的bean,它将从auth管理器接收auth令牌,以便完全填充它(加载用户的角色)。这个类需要注入一个PreAuthenticatedAuthenticationProvider
的变体,它带有整个身份验证令牌,而不仅仅是用户名。您只需使用UserDetailsService
修改原始UserDetailsByNameServiceWrapper
到该界面:
UserDetailsService
3)使用类似the documentation中所示的配置将事物连接在一起:
<bean id="preAuthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="yourUserDetailsService"/>
</bean>
</property>
</bean>
因此,实现您的需求所需要的只是一个带有一个方法的子类,还有一些额外的配置可以将它与现有的支持类连接起来。
答案 1 :(得分:0)
也许您可以实现自己的Cookie过滤器,该过滤器扩展了GenericFilterBean
配置如下所示。
<security:http ... >
....
<sec:custom-filter position="FORM_LOGIN_FILTER" ref="cookieAuthenticationFilter" />
</security:http>
看看BasicAuthenticationFilter
。原则应该非常相似。
注意:不同版本之间的BasicAuthenticationFilter
略有不同。因此,请确保找到适合的参考。