New to spring security and i will like to apply different realm (realm1) login for certain pages and a different one for the rest of the pages (realm2): Tried:
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests( authorize -> authorize
.requestMatchers(AntPathRequestMatcher.antMatcher("/customers")).authenticated()
)
.oauth2Login().loginPage("/oauth2/authorization/realm1");
http
.csrf().disable()
.authorizeHttpRequests( authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login().loginPage("/oauth2/authorization/realm2");
return http.build();
}
@Bean
public ClientRegistrationRepository clientRepository() {
return new InMemoryClientRegistrationRepository(realm1ClientRegistration(), realm2ClientRegistration());
}
private ClientRegistration realm1ClientRegistration() {
return ClientRegistration.withRegistrationId("webeam")
.clientId(realm1ClientId)
.clientSecret(realm1ClientSecret)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid","groups", "profile", "email")
.clientAuthenticationMethod(ClientAuthenticationMethod.POST)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationUri(issuerUrl+realm1+"authorize")
.tokenUri(issuerUrl+realm1+"access_token")
.userInfoUri(issuerUrl+realm1+"userinfo")
.jwkSetUri(issuerUrl+realm1+"connect/jwk_uri")
.userNameAttributeName(IdTokenClaimNames.SUB)
.build();
}
private ClientRegistration realm2ClientRegistration() {
return ClientRegistration.withRegistrationId("realm2")
.clientId(realm2ClientId)
.clientSecret(realm2ClientSecret)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid","groups", "profile", "email")
.clientAuthenticationMethod(ClientAuthenticationMethod.POST)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationUri(issuerUrl+realm2+"authorize")
.tokenUri(issuerUrl+realm2+"access_token")
.userInfoUri(issuerUrl+realm2+"userinfo")
.jwkSetUri(issuerUrl+realm2+"connect/jwk_uri")
.userNameAttributeName(IdTokenClaimNames.SUB)
.build();
}
But it seems like it ignores the matcher "/customers" and only defaults to one realm.
Thanks
I think your issue is that you keep overriding the login page value for each request and that is why you end up supporting a single realm. What I think may work for you is to have separate Spring configurations to support your 2 scenarios and make your intention clearer. For example:
@Configuration
public class SecurityConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain configurationScenario1(HttpSecurity http) throws Exception {
return http
.securityMatcher("/customers/**")
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(configurer -> configurer.loginPage("/oauth2/authorization/realm1"))
.build();
}
@Bean
@Order(Ordered.LOWEST_PRECEDENCE)
public SecurityFilterChain configurationScenario2(HttpSecurity http) throws Exception {
NegatedRequestMatcher noCustomersMatcher = new NegatedRequestMatcher(new AntPathRequestMatcher("/customers/**"));
return http
.securityMatcher(noCustomersMatcher)
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(configurer -> configurer.loginPage("/oauth2/authorization/realm2"))
.build();
}
}
NOTE 1: that configurationScenario1
makes use of .securityMatcher("/customers")
to decide whether to execute rest of the configuration or go to the next configuration.
NOTE 2: This configuration makes use of Spring Security 6, and you seem to be using Spring Security 5, just so you know that there are differences described here.