Closed igormukhin closed 5 years ago
Exerpt from AbstractAuthenticationFilterConfigurer:
private void registerDefaultAuthenticationEntryPoint(B http) {
// ...
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
RequestMatcher preferredMatcher = new AndRequestMatcher(Arrays.asList(notXRequestedWith, mediaMatcher));
// !!! registering an entry point with a matcher makes it overridable
exceptionHandling.defaultAuthenticationEntryPointFor(
postProcess(authenticationEntryPoint), preferredMatcher);
}
you can probably use this method:
@Configuration
public static class MyServiceProviderConfig extends WebSecurityConfigurerAdapter {
@Bean
SAMLConfigurerBean saml() {
return new SAMLConfigurerBean();
}
@Bean
BasicConfigurerBean basic() {
return new BasicConfigurerBean(saml().serviceProvider());
}
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.httpBasic()
.disable()
.csrf()
.disable()
.anonymous()
.and()
.apply(saml())
.serviceProvider()
// ... sp config
.http()
.authorizeRequests()
.requestMatchers(saml().endpointsMatcher())
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.apply(basic()); // NOTICE HERE APPLYING SECOND CONFIGURER
// @formatter:on
}
}
public class BasicConfigurerBean extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
private ServiceProviderBuilder serviceProvider;
public BasicConfigurerBean(ServiceProviderBuilder serviceProvider) {
this.serviceProvider = serviceProvider;
}
@Override
public void init(HttpSecurity http) throws Exception {
SAMLEntryPoint sAMLEntryPoint = serviceProvider.getSharedObject(SAMLEntryPoint.class);
LoginUrlAuthenticationEntryPoint basicEntryPoint = new LoginUrlAuthenticationEntryPoint(LOGIN_PAGE);
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints = new LinkedHashMap();
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(new
RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
RequestMatcher preferredMatcher = new AndRequestMatcher(Arrays.asList(notXRequestedWith, mediaMatcher));
entryPoints.put(preferredMatcher, basicEntryPoint);
entryPoints.put(new AnyRequestMatcher(), sAMLEntryPoint);
http
.exceptionHandling()
.authenticationEntryPoint(new DelegatingEntryPoint(entryPoints));
}
}
You can basically define a composite entry point. In this case the only trick is that you're catching the saml one, putting in inside a delegating one, and setting it back.
For the library though, one option could be simply set te samlEntryPoint as default entry point and then you'd be able to setup any other entry point in whatever stage. Or externalize a method on the serviceProvider DSL to provide a custom entryPoint (there's one but only accepts SAMLEntryPoint type).
There's a chance I don't understand what you're doing there, but if you need something to switch the login page but they don't have to co-exist together at the same time then I'd suggest loading a different security config using ConditionalOn...
type classes to load one security config or the other.
I have a similar issue, but I don't want SAMLEntryPoint
to be registered as AuthenticationEntryPoint
at all. I want it to act only as a filter at /saml/login
.
@ulisesbocchio thank you for this project and the workaround above!
Workaround for my case (maybe it can help someone):
@Bean
SAMLConfigurerBean saml() {
return new SAMLConfigurerBean(){
@Override
public void init(HttpSecurity http) throws Exception {
super.init(http);
http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
}
};
}
I had to use tricks to setup my own entry point:
I just wanted to setup my own entry point, but this library sets up SAMLEntryPoint in such a phase that you can't easily override it.
You configure it like this in SAMLConfigurerBean.java:
May be you can configure it at another phase, so it could be easily overridable.