Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use multiple 'JWK Set Uri' values in the same Spring Boot app?

I have a requirement to use two different authorization servers (two Okta instances) to validate authentication tokens coming from two different web applications inside a single Spring Boot application which is a back-end REST API layer.

Currently I have one resource server working with the following configuration:

@Configuration
@EnableWebSecurity
public class ResourceServerSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception{
    http
      .authorizeRequests().antMatchers("/public/**").permitAll()
      .anyRequest().authenticated()
      .and()
      .oauth2ResourceServer().jwt();
  }
}
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-X.okta.com/oauth2/default
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://dev-X.okta.com/oauth2/default/v1/keys

and with dependencies spring-security-oauth2-resource-server and spring-security-oauth2-jose in my Spring Boot app (version 2.2.4.RELEASE)

The end state I want to get into is, depending on a custom HTTP header set in the request, I want to pick which Okta instance my Spring Boot app uses to decode and validate the JWT token.

Ideally I would have two properties in my configuration file as follows:

jwkSetUri.X=https://dev-X.okta.com/oauth2/default/v1/keys
jwtIssuerUri.X=https://dev-X.okta.com/oauth2/default

jwkSetUri.Y=https://dev-Y.okta.com/oauth2/default/v1/keys
jwtIssuerUri.Y=https://dev-Y.okta.com/oauth2/default

I should be able to use a RequestHeaderRequestMatcher to match the header value in the security configuration. What I cannot workout is how to use two different oauth2ResourceServer instances that goes with the security configuration.

like image 791
sanjayav Avatar asked Feb 03 '20 00:02

sanjayav


2 Answers

With spring boot this is not possible to do out of the box right now. Spring Security 5.3 provides functionality to do this (spring boot 2.2.6 still doesn't support spring security 5.3). Please see following issues:

https://github.com/spring-projects/spring-security/issues/7857
https://github.com/spring-projects/spring-security/pull/7887

It is possible to do manual configuration of resource server to use multiple identity providers, by following links that i have provided. Provided links are mainly for spring boot webflux development. For basic spring boot web development please see this video:

https://www.youtube.com/watch?v=ke13w8nab-k

like image 76
Norbert Dopjera Avatar answered Oct 18 '22 22:10

Norbert Dopjera


This is possible as of Spring security 5.3+ using the JwtIssuerAuthenticationManagerResolver object

Override the configure(HttpSecurity http) inside your configuration class which extends WebSecurityConfigurerAdapter

JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerAuthenticationManagerResolver(
            "http://localhost:8080/auth/realms/SpringBootKeyClock",
            "https://accounts.google.com/o/oauth2/auth",
            "https://<subdomain>.okta.com/oauth2/default"
    );

http.cors()
            .and()
            .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/user/info", "/api/foos/**")
            .hasAnyAuthority("SCOPE_email")
            .antMatchers(HttpMethod.POST, "/api/foos")
            .hasAuthority("SCOPE_profile")
            .anyRequest()
            .authenticated()
            .and()
            .oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));
like image 41
emilpmp Avatar answered Oct 19 '22 00:10

emilpmp