1

我使用 Spring Security 来保护使用 Spring 构建的 RESTful Web 服务,但过去请求使用身份验证标头进行身份验证。现在,当用户的凭据在 cookie 中时,我需要保护这样的应用程序。

我试图找出从 cookie 中提取用户信息并将其放入身份验证标头中的最佳方法,或者理想情况下只是将 cookie 的值用于bean中的loadUserByUsername方法。UserDetailsService

到目前为止,我已经提出了一些关于如何做到这一点的想法:

  1. 我可以添加一个HandlerInterceptor以使用 cookie 将身份验证标头添加到请求中。但是,并非所有请求都需要身份验证,所以如果我这样做了,我希望将其应用于某些方法或请求映射而不是其他方法,我不知道该怎么做。

  2. 我可以实现AuthenticationEntryPoint本教程中所示的那样。在那个教程中虽然我真的不明白为什么他有response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );作为commence方法的主体。在我的用例中,我会在那里使用 cookie 添加身份验证标头吗?

  3. 我可以在所有控制器方法的第一行中使用自定义方法执行安全检查。似乎当您遵循 Spring Security 的理想路径时,它是一个非常好的解决方案。不过,我需要做的似乎偏离了这一点,我的要求实际上很简单。也许我最好用简单的老式方式来做这件事?

  4. 一些我不知道/没有想到的更好的主意!

感谢您的帮助和想法!

4

2 回答 2

3

如果我正确地满足了您的要求,那么使用 Spring Security 的预身份验证框架类来实现所需的身份验证机制可能是最简单的。

一般来说,这些类是为了支持这样的场景而设计的,在这些场景中,身份验证机制由一些外部系统提供,确保 http 请求包含某种可以被任何 webapp 使用的身份验证信息。在您的情况下,身份验证信息似乎位于可用于识别用户的 cookie 中。

假设您已经有一个UserDetailsService按用户名查找用户的实现,您可以很容易地实现您的要求:

1)创建一个AbstractPreAuthenticatedProcessingFilter实现抽象方法的子类,getPreAuthenticatedPrincipal(HttpServletRequest)从cookie中提取主体(用户名)。getPreAuthenticatedCredentials()如果请求中没有凭据,还有另一种抽象方法 ( ) 可以简单地返回 null。抽象超类中已经实现的逻辑然后创建一个包含提取的主体的身份验证令牌,并将其提交给身份验证管理器。

2) 创建一个 bean 类型PreAuthenticatedAuthenticationProvider,它将从身份验证管理器接收身份验证令牌,以便完全填充它(加载用户的角色)。这个类需要注入一个变体,UserDetailsService它接受整个身份验证令牌,而不仅仅是用户名。您可以简单地使用UserDetailsByNameServiceWrapper使您的原件适应UserDetailsService该界面:

<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>

3)使用类似于文档中显示的配置将事物连接在一起:

<security:http>
    ...
    <security:custom-filter position="PRE_AUTH_FILTER" ref="preAuthFilter" />
</security:http>

<bean id="preAuthFilter" class="com.whatever.YourPreAuthFilter"/>

<security:authentication-manager>
    <security:authentication-provider ref="preAuthAuthProvider" />
</security:authentication-manager>

因此,实现您的要求所需要的只是一个具有一个方法的子类,以及一些额外的配置来将它与现有的支持类连接起来。

于 2013-05-13T09:42:39.133 回答
0

也许您可以实现自己的 cookie 过滤器,它可以扩展GenericFilterBean

配置如下。

<security:http ... >
    ....
    <sec:custom-filter position="FORM_LOGIN_FILTER" ref="cookieAuthenticationFilter" />                                         
</security:http>  

看看BasicAuthenticationFilter。原理应该很相似。

注意:BasicAuthenticationFilter不同版本之间存在少许差异。因此,请确保您找到合适的供参考。

于 2013-05-13T02:28:49.023 回答