问题描述
我正在使用的当前安全配置:
@Configuration
public class SecurityConfig {
/**
* Default order of 3 as per Spring documentation.
*/
@Configuration
@EnableWebSecurity
@EnableResourceServer
public static class OAuth2SecurityConfiguration extends ResourceServerConfigurerAdapter {
private final TokenStore tokenStore;
@Autowired
public OAuth2SecurityConfiguration(TokenStore tokenStore) {
this.tokenStore = tokenStore;
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.tokenStore(tokenStore);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.apply(CommonSecurityConfiguration
.commonSecurityConfiguration())
.and()
.authorizeRequests().anyRequest()
.authenticated();
}
}
@Configuration
@Order(1)
public static class SecretAuthSecurityConfiguration extends WebSecurityConfigurerAdapter {
private JPAAuthenticationProvider authenticationProvider;
@Autowired
public void setAuthenticationProvider(JPAAuthenticationProvider authenticationProvider) {
this.authenticationProvider = authenticationProvider;
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider);
}
@Bean
public FilterRegistrationBean<Filter> secretFilterRegistrationBean() {
var filterRegistrationBean =
new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(
new SecretFilter();
return filterRegistrationBean;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatchers("/resource1/api/**","/resource2/api/**")
.and()
.addFilterafter(this.secretFilterRegistrationBean().getFilter(),logoutFilter.class)
.apply(CommonSecurityConfiguration
.commonSecurityConfiguration());
}
}
public static class CommonSecurityConfiguration
extends AbstractHttpConfigurer<CommonSecurityConfiguration,HttpSecurity> {
@Override
public void init(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable();
}
public static CommonSecurityConfiguration commonSecurityConfiguration() {
return new CommonSecurityConfiguration();
}
}
}
我是Spring Security的新手,我的目标是构建一个应用程序,该应用程序允许对应用程序中的不同路径进行不同类型的身份验证。
据我从文章和Spring文档中了解到的那样,在使用ANT匹配器之类的东西来管理过滤器链时,您具有很大的灵活性。
在上面的代码段中,我尝试配置2个过滤器链-每个过滤器链对应一种身份验证类型:
- OAuth2,基于令牌的安全性配置-在静态类
OAuth2SecurityConfiguration
中进行了描述-我在其中使用了注释@EnableResourceServer
,该注释会自动将org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter
添加到新的过滤器链中。根据有关@EnableResourceServer
的Spring文档:
public class SecretFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,FilterChain filterChain)
throws IOException,servletexception {
log.info("Inside SecretFilter.");
String secret = this.resolveSecret(httpServletRequest);
if (secret.isValid()) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(null,null,null));
}
filterChain.doFilter(httpServletRequest,httpServletResponse);
/**
* Clearing the security context after the request is made.
*/
SecurityContextHolder.getContext().setAuthentication(null);
}
生成的过滤器链:
o.s.s.web.DefaultSecurityFilterChain: Creating filter chain:a OrRequestMatcher [requestMatchers=[Ant [pattern='/resource1/api/star.star'],Ant [pattern='/resource2/api/star.star']]]
- WebAsyncManagerIntegrationFilter
- SecurityContextPersistenceFilter
- HeaderWriterFilter
- CorsFilter
- logoutFilter
- SecretFilter <------- here is my filter
- RequestCacheAwareFilter
- SecurityContextHolderAwareRequestFilter
- AnonymousAuthenticationFilter
- SessionManagementFilter
- ExceptionTranslationFilter
o.s.s.web.DefaultSecurityFilterChain: Creating filter chain: org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration$NotOAuthRequestMatcher
- WebAsyncManagerIntegrationFilter
- SecurityContextPersistenceFilter
- HeaderWriterFilter
- CorsFilter
- logoutFilter
- OAuth2AuthenticationProcessingFilter
- RequestCacheAwareFilter
- SecurityContextHolderAwareRequestFilter
- AnonymousAuthenticationFilter
- SessionManagementFilter
- ExceptionTranslationFilter
- FilterSecurityInterceptor
应该处理这种身份验证的静态配置类已用@Order(1)
注释标记,因为我希望请求首先通过带有自定义过滤器的过滤器链传递,否则,如果请求不是针对指定的路径,例如/resource1/api/**
,然后通过OAuth过滤器链。
例如,当我对路径/resource1/api/X
进行常规请求时,一切进展顺利,并且过滤器链得到执行。但是,当收到除上述指定路径以外的其他路径上的请求时,控制台将向我显示以下内容:
2020-09-22 01:00:03.698 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-09-22 01:00:03.698 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-09-22 01:00:03.698 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-09-22 01:00:03.698 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 4 of 12 in additional filter chain; firing Filter: 'CorsFilter'
2020-09-22 01:00:03.703 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 5 of 12 in additional filter chain; firing Filter: 'logoutFilter'
2020-09-22 01:00:03.703 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 6 of 12 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-09-22 01:00:03.715 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-09-22 01:00:03.716 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-09-22 01:00:03.717 DEBUG 928 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /profile/?date=2020-09-21T22:00:03Z reached end of additional filter chain; proceeding with original chain
2020-09-22 01:00:03.718 INFO 928 --- [nio-8080-exec-4] c.s.p.s.filters.SecretFilter : Inside SecretFilter.
为什么SecretFilter在OAuth过滤器链的末尾执行?它没有使用@Order
注释或其他任何注释。我的路径不应该匹配,因此包含过滤器的过滤器链不应该被触发。看起来很清楚,但这是我无法获得的小东西。
我的直觉是,过滤器以默认的Ordered.LOWEST_PRECEDENCE
顺序注册并以某种方式放置,并且在FilterChainProxy
完成当前多路复用链的工作后执行。
任何帮助或参考,以了解更多有关它的信息。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)