春季安全性5:在OAuth2检查之前触发了LogoutFilter

时间:2018-10-16 09:59:54

标签: spring-security oauth-2.0

我们正在将一个使用带有xml配置的spring security 3.2的大型项目迁移到具有spring-security 5.0和编程配置的当前spring boot堆栈中。 通过在过滤器链的末尾将注销成功处理程序注册为自定义过滤器,可以很好地完成旧的注销操作。 旧的xml配置的相关部分:

[...]
<http pattern="/oauth/(users|clients)/.*" request-matcher="regex" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint" use-expressions="true" xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false" />
    <intercept-url pattern="/oauth/users/revoke" method="POST" access="#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient())" />
    <intercept-url pattern="/**" access="denyAll()" />
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
    <expression-handler ref="oauthWebExpressionHandler" />
    <custom-filter ref="revokeFilter" before="LAST" />
</http>

[...]
<bean id="revokeFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg>
        <bean class="com.company.management.authorization.oauth2.RevokeSuccessHandler" />
    </constructor-arg>
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
        </list>
    </constructor-arg>
    <property name="filterProcessesUrl" value="/oauth/users/revoke" />
</bean>
[...]

这导致了以下过滤器链:

Security filter chain: [
  SecurityContextPersistenceFilter
  WebAsyncManagerIntegrationFilter
  OAuth2AuthenticationProcessingFilter
  SecurityContextHolderAwareRequestFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
  LogoutFilter
]

当我现在通过以下方式添加注销成功处理程序来配置资源服务器时:

@Override
public void configure( HttpSecurity http ) throws Exception
{
    http.regexMatcher( "/oauth/(users|clients)/.*" )
        .anonymous( ).disable( ).authorizeRequests( )
        .regexMatchers( HttpMethod.POST, "/oauth/users/revoke" )
        .access( "#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient())" )
        .antMatchers( "/**" ).denyAll( )
        .and( ).sessionManagement( ).sessionCreationPolicy( SessionCreationPolicy.STATELESS )
        .and( ).csrf( ).disable( ).exceptionHandling( )
        .accessDeniedHandler( this.oAuth2AccessDeniedHandler )
        .defaultAuthenticationEntryPointFor( this.oauthAuthenticationEntryPoint,new AntPathRequestMatcher( "/**" ) )
        .and( ).logout( ).logoutUrl( "/oauth/users/revoke" ).logoutSuccessHandler( revokeSuccessHandler( ) );
}

在应用OAuth2AuthenticationProcessingFilter之前,将触发注销处理程序,因此未进行任何身份验证。过滤器链如下所示:

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  LogoutFilter
  OAuth2AuthenticationProcessingFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

注销成功处理程序中的身份验证对象为null,并且处理程序中的逻辑(基于给定的身份验证对象进行了一些其他检查)不再起作用。 如果我删除注销成功处理程序,则OAuth2AuthenticationProcessingFilter检查将正确完成,并且身份验证将按预期进行(但是,当然会丢失注销)。 如果我更改注销处理程序中的逻辑并从请求的Authorization标头中剥离令牌,则可以从令牌存储加载授权,然后再次手动实施访问检查,但这似乎不是这种方式应该做的...

所以,主要的问题是,LogoutFilter是在过滤器链中的OAuth2AuthenticationProcessingFilter之前设置的,我找不到改变顺序的方法。 我试图将属性security.oauth2.resource.filter-order设置为3,但这没有帮助。我还为@Order注释尝试了其他值,但是没有运气。 我想办法可能是通过执行类似{{1} 但是我无法实例化必要的LogoutFilter类,因为它需要LogoutHandlers列表作为构造函数参数,而我没有(传递null会导致错误,并且尝试自动装配也行不通)。

那么,实现正确的过滤器顺序的正确方法是什么?

0 个答案:

没有答案
相关问题