403 Forbidden Using Springboot When Hitting Okta Userinfo endpoint

Viewed 306

I'm trying to set up Okta as a sign on for a set of subpaths in my spring boot app. I'm configuring the auth resource details with:

    @Bean(name = "oktaOAuthClient")
public AuthorizationCodeResourceDetails oktaOAuthAdminClient(@Qualifier("oktaAdminConfiguration") OktaConfigurationProperties oktaAdminCongfig,
        ICredentialsApi credentialsApi) {
    String redirectUrl = UriComponentsBuilder.fromUriString("http://localhost:8091/")
            .path(ConfigurationRequestPaths.ADMINISTRATION_LANDING)
            .build(false)
            .toUriString();

    AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();

    client.setClientId(oktaAdminCongfig.getClientId());
    client.setClientSecret(oktaAdminCongfig.getClientSecret());
    client.setAccessTokenUri(oktaAdminCongfig.getAccessTokenUri());
    client.setUserAuthorizationUri(oktaAdminCongfig.getUserAuthorizationUri());
    client.setClientAuthenticationScheme(AuthenticationScheme.header);
    client.setPreEstablishedRedirectUri(redirectUrl);
    client.setScope(OKTA_SCOPES);
    client.setUseCurrentUri(false);

    client.setScope(OKTA_SCOPES);

    return client;
}

These and other settings are found from the application.properties manually and are set as:

okta.admin.clientId={id}
okta.admin.clientSecret={secret}
okta.admin.accessTokenUri=https://dev-{value}.okta.com/oauth2/default/v1/token
okta.admin.userAuthorizationUri=https://dev-{value}.okta.com/oauth2/default/v1/authorize
okta.admin.issuer=https://dev-{value}.okta.com/oauth2/default
okta.admin.userInfoUrl=https://dev-{value}.okta.com/oauth2/default/v1/userinfo 

Then I've made a filter with (Note, is the clientId set in the UserTokenInfoServices meant to be the client id from the okta client id/client secret?):

@Bean(name = "oktaFilter")
public Filter oktaFilter(@Qualifier("oktaOAuthClient") AuthorizationCodeResourceDetails oktaOAuthClient,
        @Qualifier("oktaOAuthResource") ResourceServerProperties resource,
        @Qualifier("oktaOAuthRestTemplate") OAuth2RestTemplate oktaOAuthRestTemplate) {
    ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler();
    failureHandler.setDefaultFailureUrl("/");

    OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(ConfigurationRequestPaths.ADMINISTRATION_LANDING);
    UserInfoTokenServices tokenServices = new UserInfoTokenServices(resource.getUserInfoUri(), oktaOAuthClient.getClientId());

    tokenServices.setRestTemplate(oktaOAuthRestTemplate);
    filter.setRestTemplate(oktaOAuthRestTemplate);
    filter.setTokenServices(tokenServices);

    SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
    successHandler.setUseReferer(true);
    filter.setAuthenticationSuccessHandler(successHandler);
    filter.setAuthenticationFailureHandler(failureHandler);

    return filter;
}

Finally I've set up the WebSecurityConfigurerAdapter with the following:

        http.antMatcher("/config/**")
                .authorizeRequests()
                .antMatchers("/config")
                .permitAll()
                .anyRequest().authenticated().and()
                .exceptionHandling()
           .authenticationEntryPoint(oktaLoginHandler)SimpleUrlAuthenticationSuccessHandler(ConfigurationRequestPaths.ADMINISTRATION_LANDING))
                .and()
                .logout().addLogoutHandler(oktaLogoutHandler).logoutSuccessUrl(externalAccessUrl).permitAll().and()
                .addFilterBefore(oktaFilter, BasicAuthenticationFilter.class);
    }

The redirect for the subpath works correctly and goes to a sign in page, but I get an error after signing in that warns:

org.springframework.security.authentication.BadCredentialsException: Could not obtain user details from token...Caused by: org.springframework.security.oauth2.common.exceptions.InvalidTokenException:

I believe this likely has to do with getting a 403 when hitting the okta userinfo endpoint:

Request is to process authentication
Retrieving token from https://dev-{value}.okta.com/oauth2/default/v1/token
Encoding and sending form: {grant_type=[authorization_code], code=[{code}], redirect_uri=[http://localhost:8091/config], client_id=[{id}], client_secret=[{secret}]}
HTTP GET https://dev-{value}.okta.com/oauth2/default/v1/userinfo
Accept=[application/json, application/*+json]
Response 403 

I've also tried the okta starter but it seems to break when used with another oauth login to github for another set of subpaths in the application. The spring version I'm using doesn't include the .oauthLogin() and other settings for httpsecurity that I've seen some guides on.

edit: Adding my spring dependency list for more clarification:

org.springframework:spring-beans:5.1.20.RELEASE
org.springframework:spring-context:5.1.20.RELEASE
org.springframework:spring-jdbc:5.1.20.RELEASE
org.springframework:spring-tx:5.1.20.RELEASE
org.springframework:spring-web:5.1.20.RELEASE
org.springframework:spring-webmvc:5.1.20.RELEASE
org.springframework:spring-test:5.1.20.RELEASE
    
org.springframework.boot:spring-boot-actuator:2.1.18.RELEASE
org.springframework.boot:spring-boot-autoconfigure:2.1.18.RELEASE
org.springframework.boot:spring-boot-configuration-processor:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-actuator:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-security:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-thymeleaf:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-web:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-test:2.1.18.RELEASE
    
org.springframework.retry:spring-retry:1.3.1
    
org.springframework.security:spring-security-config:5.1.13.RELEASE
org.springframework.security:spring-security-core:5.1.13.RELEASE
org.springframework.security:spring-security-ldap:5.1.13.RELEASE
org.springframework.security:spring-security-web:5.1.13.RELEASE
    
org.springframework.security.oauth:spring-security-oauth2:2.3.8.RELEASE

org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.1.18.RELEASE
1 Answers

It sounds like you might be using the older Spring Security OAuth project: spring-security-oauth?

This project has been deprecated. The newer Spring Security OAuth2 modules are great, and they are now first-class citizens, in Spring Security (they live in the official project now). Along with this Spring Boot 1.x is EoL, and is no longer getting patches and security updates.

Most of the guides you are seeing likely reference the newer libraries (e.g. things like .oauthLogin()).

Sorry for the typical StackOverflow answer of "don't do X", but here is what I would recommend:

  1. Update your Spring Boot version
  2. Migrate the newer OAuth libraries
  3. Then add your new logic (this should be much easier after updating)

If you are already on Spring Boot 2 and the newer OAuth lib, let me know, and we can try to figure out why you don't have the newer HttpSecurity methods.

Related