我的项目有两个身份验证提供程序:Google OAuth2客户端(oauth2入门依赖)和第二个自定义AuthenticationProvider
。
我有两个antMatcher
:/api/**
和/app/**
。
是否可以通过我的自定义身份验证提供程序为/app/**
和O {2}授权?
因为我不想为REST API启用OAuth2,但希望为应用程序的其余部分启用OAuth SSO。
如何为不同的身份验证提供程序指定不同的URL模式?
修改
按照我的配置进行操作(Spring Boot 2.0.2):
/api/**
尝试了不同的配置,但没有用
答案 0 :(得分:0)
AuthenticationProvider有一个方法:supports(类身份验证) 接受身份验证令牌的令牌,如果返回false,则AuthenticationManager将不会调用该提供程序。
因此,您可以在Authentication Token中放入一个自定义字段,以指示正在调用哪个URI,Authentication界面具有getDetails()方法,该方法可以返回Object,还可以提供其他信息。
为此,您需要创建自定义AuthenticationDetails和AuthenticationDetailsSource,可以扩展WebAuthenticationDetails和WebAuthenticationDetailsSource。 WebAuthenticationDetailsSource具有一个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”
。