春季安全-OAuth2和CustomAuthenticationProvider。如何为每个配置不同的URL模式?

时间:2019-07-12 03:40:30

标签: spring spring-boot spring-security spring-security-oauth2

我的项目有两个身份验证提供程序:Google OAuth2客户端(oauth2入门依赖)和第二个自定义AuthenticationProvider

我有两个antMatcher/api/**/app/**

是否可以通过我的自定义身份验证提供程序为/app/**和O {2}授权?

因为我不想为REST API启用OAuth2,但希望为应用程序的其余部分启用OAuth SSO。

如何为不同的身份验证提供程序指定不同的URL模式?

修改

按照我的配置进行操作(Spring Boot 2.0.2):

/api/**

尝试了不同的配置,但没有用

2 个答案:

答案 0 :(得分:0)

AuthenticationProvider有一个方法:supports(类身份验证) 接受身份验证令牌的令牌,如果返回false,则AuthenticationManager将不会调用该提供程序。

因此,您可以在Authentication Token中放入一个自定义字段,以指示正在调用哪个URI,Authentication界面具有getDetails()方法,该方法可以返回Object,还可以提供其他信息。

为此,您需要创建自定义AuthenticationDetails和AuthenticationDetailsS​​ource,可以扩展WebAuthenticationDetails和WebAuthenticationDetailsS​​ource。 WebAuthenticationDetailsS​​ource具有一个buildDetails方法,该方法使您可以访问HttpServletRequest。

答案 1 :(得分:0)

由于您有两个身份验证提供程序,因此需要配置两个身份验证管理器。这是示例XML配置供您参考:

<security:authentication-manager id="appAuthenticationManager">
    <security:authentication-provider ref="appAuthenticationProvider"/>
</security:authentication-manager>

<security:authentication-manager id="apiAuthenticationManager">
    <security:authentication-provider ref="apiAuthenticationProvider"/>
</security:authentication-manager>

然后为端点配置安全保护规则。

<sec:filter-security-metadata-source id="appServerSecurityMetadataSource"
                                     request-matcher="ant"
                                     use-expressions="true">
    <sec:intercept-url pattern="/oauth/check_token" access="isFullyAuthenticated() and hasRole('PRIVATE_SERVICE')"/>
    <sec:intercept-url pattern="/oauth/token" access="isFullyAuthenticated() and hasRole('PRIVATE_SERVICE')"/>
    <sec:intercept-url pattern="/oauth/jwt-token" access="isFullyAuthenticated() and hasRole('PRIVATE_SERVICE')"/>
    <sec:intercept-url pattern="/**" access="denyAll()"/>

    <sec:expression-handler ref="securityExpressionHandler"/>
</sec:filter-security-metadata-source>


<sec:filter-security-metadata-source id="apiServerSecurityMetadataSource"
                                     request-matcher="ant"
                                     use-expressions="true">
    <sec:intercept-url pattern="/users/**" access="isFullyAuthenticated() and hasRole('ACTIVE_USER')"/>
    <sec:intercept-url pattern="/**" access="denyAll()"/>

    <sec:expression-handler ref="securityExpressionHandler"/>
</sec:filter-security-metadata-source>

然后配置过滤器安全拦截器:(也为apiAuthenticationManager配置类似的拦截器)

<bean id="appSecurityInterceptorFilter" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="appAuthenticationManager"/>
    <property name="accessDecisionManager" ref="accessDecisionManager"/>
    <property name="securityMetadataSource" ref="appServerSecurityMetadataSource"/>
</bean>

最后一步是注册这些过滤器bean:

<bean id="appServerSecurityFilterRegistration" class="org.springframework.boot.web.servlet.FilterRegistrationBean">
    <property name="filter" ref="appSecurityInterceptorFilter"/>
    <property name="enabled" value="false"/>
</bean>

编辑:要绕过整个过滤链的某些请求,请执行以下操作:

为所有/api/**请求创建路径匹配器。

<bean id="apiRequestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
    <constructor-arg index="0" value="/api/**"/>
</bean>

创建一个空的过滤器链以绕过/api/**请求的所有过滤器。

<bean id="apiFilterChain" class="org.springframework.security.web.DefaultSecurityFilterChain">
    <constructor-arg name="requestMatcher" ref="apiRequestMatcher"/>
    <constructor-arg name="filters">
        <list/>
    </constructor-arg>
</bean>

最后,将其注册以过滤链代理。

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <constructor-arg>
        <list>
            <ref bean="apiFilterChain"/>
        </list>
    </constructor-arg>
</bean>

要将这些请求委托给您的自定义提供商,请遵循我之前共享的步骤。

您也可以尝试<http pattern="/api/**" security="none"/>绕过过滤器链。 Spring 3.1将filters=”none”替换为security=”none”