目前,我在服务中使用了两种端点:
/portal/**
:我需要添加过滤器PortalAuthorizationFilter
OthersAuthorizationFilter
重要的是,OthersFilter
不应应用于/portal/**
呼叫。
我已经创建了WebSecurityConfigurerAdapter
。我当前的代码是:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(new JWTExceptionHandlerFilter(objectMapper, messageSource), BasicAuthenticationFilter.class)
.cors().and()
.csrf().disable()
.antMatcher("/portal/**")
.addFilter(new PortalAuthorizationFilter())
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilter(new OthersAuthorizationFilter());
}
}
调用/portal/**
,到达PortalAuthorizationFilter
但又到达OthersAuthorizationFilter
时,我已经调试了这段代码。
我不太想怎么解决。
有什么想法吗?
答案 0 :(得分:0)
您需要创建另一个配置类,该类还将扩展WebSecurityConfigurerAdapter,在那里您将url与antMatchers匹配并添加过滤器。无论哪种模式匹配都将运行该安全配置 阅读此post
答案 1 :(得分:0)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/portal/**").... //the configuration only
//applies when sb hitting /portal/**
}
}
如果您想为另一个网址进行其他配置,则需要覆盖另一个WebSecurityConfigurerAdapter
:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
@Order(101) //@Order(100) is default
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http... //without antMatcher(...) default will be used "/**",
//so it take all request. So the order of this class should be
// higher
}
}
如果您想使用过滤器方法(.addFilter(new OthersAuthorizationFilter());
,那么在您的doFilter
方法中,您应该实现:
doFilter(...) {
if(match(request, "/portal/**")
....
}
不幸的是,AuthenticationProvider
不会给您这种可能性,它不知道url,而只是凭据。如果您想要更多read spring-security-architecture。
答案 2 :(得分:0)
另一个选择是使用委托模式。想象一下,如果您有一个看起来像这样的过滤器
public class PickAndChooseFilter extends OncePerRequestFilter {
private AntPathRequestMatcher matcher = new AntPathRequestMatcher("/portal/**");
private final Filter portalAuthorizationFilter;
private final Filter othersAuthorizationFilter;
public PickAndChooseFilter(Filter portalAuthorizationFilter, Filter othersAuthorizationFilter) {
this.portalAuthorizationFilter = portalAuthorizationFilter;
this.othersAuthorizationFilter = othersAuthorizationFilter;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (matcher.matches(request)) {
portalAuthorizationFilter.doFilter(request, response, filterChain);
} else {
othersAuthorizationFilter.doFilter(request, response, filterChain);
}
}
}
然后代替
.addFilter(new PortalAuthorizationFilter())
.addFilter(new OthersAuthorizationFilter())
您只需拥有
.addFilter(new PickAndChooseFilter(
new PortalAuthorizationFilter(),
new OthersAuthorizationFilter()
)