Search code examples
spring-bootspring-mvcspring-oauth2pingfederatespring-boot-starter-oauth2-client

spring-boot-starter-oauth2-client not sending client_id to external SSO


I'm using spring-security-starter-oauth2-client to try and configure a Spring Boot app to use my company's PingFederate SSO page, which is hosted on a different domain than the app. With my current configuration, an unauthorized user will be forwarded to the SSO page, but none of the necessary parameters (such as the client_id) are being passed in the URL, so it fails.

application.yaml

spring:
  mvc.servlet.path: /my-app/
  security:
    oauth2:
      client:
        registration:
          pingfed:
            authorization-grant-type: authorization_code
            client-id: foo
            client-secret: bar
            scope: openid, profile, email
        provider:
          pingfed:
            authorization-uri: https://sso.company.com/as/authorization.oauth2
            issuer-uri: https://sso.company.com
            token-uri: https://sso.company.com/as/token.oauth2
            user-info-uri: https://sso.company.com/idp/userinfo.openid
            jwk-set-uri: https://sso.company.com/pf/JWKS

Oauth2Config.java

@Configuration
public class OAuth2ClientConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .oauth2Login();
        return http.build();
    }
}

When I run the app and hit a protected page, it forwards me to the login page https://sso.company.com/as/authorization.oauth2 and I get a "client_id not found" type error.

When I hit this SSO from a working (non-Spring) application, the url includes the expected params: https://sso.company.com/as/authorization.oauth2?client_id=foo&code_chanllenge=xyz&scope=openid&etc

What am I missing? Is there a way to change the login url without having to add all the params manually?

UPDATE
I managed to get it to work as expected by commenting out my "mvc.servlet.path". I believe this is an issue of Spring putting the default login at http://localhost:8080/oauth2/authorization/pingfed, while my app runs at http://localhost:8080/my-app/, but I'm not sure how to configure around it yet.


Solution

  • Not sure how I missed this, but the answer was to change the authorizationEndpoint.baseUri in the SecurityFilterChain configuration to include the mvc servlet path before the default login. (Spring will automatically add the "registrationId" to the end of the path.)

    @Configuration
    public class OAuth2ClientConfig {
        @Bean
        public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .oauth2Login()
                        .authorizationEndpoint()
                            .baseUri("/my-app/oauth2/authorization")
            return http.build();
        }
    }