6

New to spring boot and I'm working on an application that already had some Oauth2 authentication done for signing in with azure. I was tasked with setting up some auth for another API and now I have two registrations(client id/secret/grant-type) in my application-local.properties.

spring.security.oauth2.resource.jwk.key-set-uri=xxxxxxxx
spring.security.oauth2.client.registration.azure.client-secret=xxxx
spring.security.auth2.client.registration.azure.client-id=xxxxx
spring.security.oauth2.client.registration.azure.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.azure.client-name=azure
spring.security.oauth2.client.registration.azure.provider=azure
spring.security.oauth2.client.registration.azure.scope=openid,profile,email,offline_access

spring.security.oauth2.client.provider.test.token-uri=xxxxx
spring.security.oauth2.client.registration.test.client-id=xxxxx
spring.security.oauth2.client.registration.test.client-secret=xxxxx
spring.security.oauth2.client.registration.test.authorization-grant-type=client_credentials

example of login prompt

example of login prompt

This works. The problem now is when visiting the application for the first time, you are prompted to choose which service you would like to login with, either azure or test. I would like to be able to set a default for this and use azure for logging into the application so the user isn't prompted.

        http.authorizeRequests()
                .antMatchers("/impersonate/**").hasAnyRole(roleAdmin)
                .antMatchers("/login", "/health").permitAll()
                .anyRequest().authenticated()
                .antMatchers("/logout").hasRole(prevRoleAdmin)
                .anyRequest().fullyAuthenticated()
                .and()
                .csrf().disable()
                .logout()
                .logoutSuccessUrl("/admin")
                .and()

                .oauth2Login() // Is there a way to pass which registration it should use after this?

                .userInfoEndpoint()
                .oidcUserService(this.oidcUserService())
        ;

Is there any way to set this to seek out and use the creds for azure?

Bashir
  • 2,057
  • 5
  • 19
  • 44
e92M3
  • 85
  • 1
  • 8

2 Answers2

8

By default, Spring Security shows the chooser page, but you can set the login page to a specific client:

@Configuration
public class RedirectToAzureConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            // ... 
            .oauth2Login(oauth2 -> oauth2
                .loginPage("/oauth2/authorization/azure")
            );
    }

}

For every client listed in your application.properties, Spring Security will respond to /oauth2/authorization/{registrationId} requests and negotiate with the corresponding authorization server to get the user logged in.

If you need to programmatically decide what to redirect to, you can register an AuthenticationEntryPoint instead of setting the loginPage().

jzheaux
  • 7,042
  • 3
  • 22
  • 36
  • Seems Dirty but it works. I just needed the option of using two authorization grant types for the same registration id, which apparently is not possible. So I ended up duplicating the registration id with a different grant type, leading to above mentioned problem. – p.sherif Jul 30 '20 at 19:37
  • Good feedback - I simplified my response a bit, see if that helps. – jzheaux Jul 31 '20 at 22:36
  • 1
    hey, is there any proper way in webflux? this answer is what exactly i looking for, but cannot achieve in webflux security. – denizg Sep 03 '20 at 18:50
  • @jzheaux - I have seen your Multi Tenancy talk from 2019 and the question is whether this will be taken care in Framework itself? Can we add a property baserequestURI or requestContext in Client Registration Bean and it automagically detects property and routes to appropriate Oauth2 Provider!! Posted same question - https://stackoverflow.com/questions/68367181/multi-tenancy-with-spring-security-oauth2-client – Arpan Sharma Jul 15 '21 at 12:41
1

Webflux way of defining the Authentication Entry Point:

@Configuration
public class RedirectToAzureConfig {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {

        http
            // ...
            .oauth2Login()
            .and()
            .exceptionHandling()
                .authenticationEntryPoint(new RedirectServerAuthenticationEntryPoint("/oauth2/authorization/azure")));
        return http.build();
    }
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
tschlegel
  • 21
  • 2