问题
I researched this and found this Answer on SO.
I do however have the complementary question to this one:
I have a set of filters, that i want to be applied to ALL requests, EXCEPT special cases (eg.: all paths except /mgmt/** and /error/**).
This cannot be done using the same method presented in the linked answer, as I would add the filters to the default http-security Object, which would then apply for the special cases too.
is there a thing like "negative matchers", allowing me to do something like:
http.negativeAntMatchers("/mgmt/**).addFilter(...)
to add a filter for everything except /mgmt/** ?
my code:
This is the config for "/mgmt", placing the ManagementBasicAuthFilter in the chain - this works, as no endpoints except "/mgmt/**" ask for basic auth.
@Order(1)
@Configuration
@RequiredArgsConstructor
public static class ManagementSecurityConfig extends WebSecurityConfigurerAdapter {
private final AuthenticationManager authenticationManager;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("mgmt/**")
.csrf().disable()
.headers().frameOptions().sameOrigin()
.cacheControl().disable()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(new ManagementBasicAuthenticationFilter(authenticationManager,
getAuthenticationEntryPoint(), "/mgmt"), BasicAuthenticationFilter.class)
.authorizeRequests()
.anyRequest()
.permitAll();
}
private BasicAuthenticationEntryPoint getAuthenticationEntryPoint() {
BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
entryPoint.setRealmName("myApp");
return entryPoint;
}
}
This is the config for all entrypoints, EXCEPT mgmt - all filters in this file should NOT apply to /mgmt/**
@Order(2)
@Configuration
@RequiredArgsConstructor
@Import({ ResourceServerTokenServicesConfiguration.class })
@EnableOAuth2Client
public static class OAuthSecurityConfig extends WebSecurityConfigurerAdapter {
private final OAuth2ClientContextFilter clientContextFilter;
private final OAuth2ClientAuthenticationProcessingFilter ssoFilter;
private final StatePropagatingLoginRedirectFilter statePropagatingLoginRedirectFilter;
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/mgmt/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().frameOptions().sameOrigin()
.cacheControl().disable()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
request -> true)
.and()
.addFilterAfter(statePropagatingLoginRedirectFilter, AbstractPreAuthenticatedProcessingFilter.class)
.addFilterAfter(ssoFilter, statePropagatingLoginRedirectFilter.getClass())
.addFilterAfter(clientContextFilter, ssoFilter.getClass())
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
When i Request eg.: "/mgmt/health", i get prompted for basic auth, but after login, the filters in the (statePropagating, sso, clientContext) still get applied - why is this?
回答1:
If I understand your question right, you don't want a filter to be applied to /mgmt
then you could use
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
// Overridden to exclude some url's
web.ignoring().antMatchers("/mgmt");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// configure the other url's as required
}
}
回答2:
thanks to kimhom and his answer in combination with Nicholas and e.g.78 i figured it out - web.ignoring
does not work, for reasons i want to investigate later - what i forgot about is, that spring will automatically add all filters present as Beans to all filter chains. to prevent this, one can either
- not register filters as beans and instantiate them manually where they are needed
add a FilterRegistrationBean for the filters in question and disable registration for them like this:
@Bean public FilterRegistrationBean disableMyFilterBean(MyFilterBean filter) { FilterRegistrationBean registration = new FilterRegistrationBean(filter); registration.setEnabled(false); return registration; }
Then my filters are only applied where i want them to - i do not even need to provide WebSecurity.ignoring
matchers
回答3:
You can configure spring security to ignore some url patterns using web.ignoring In your case
web.ignoring().antMatchers("/mgmt/**");
回答4:
You'll need to permit all requests in "/mgmt/**" and make other requests authenticated, try something like that.
http
.authorizeRequests()
.antMatchers("**").hasAnyAuthority("ANY_AUTHORITY")
.antMatchers("/mgmt/**").permitAll()
.anyRequest().authenticated()
来源:https://stackoverflow.com/questions/52039388/spring-security-add-filter-to-all-endpoint-except-one