Skip to content

JwtDecoder for multiple issuers #10943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ch4mpy opened this issue Mar 8, 2022 · 5 comments
Closed

JwtDecoder for multiple issuers #10943

ch4mpy opened this issue Mar 8, 2022 · 5 comments
Assignees
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@ch4mpy
Copy link
Contributor

ch4mpy commented Mar 8, 2022

Expected Behavior

It would be nice to have

  • a JwtDecoder supporting multiple token issuers
  • spring-boot to auto configure such a multi-issuers JwtDecoder when configuration has several issuer-uris

Current Behavior

spring.security.oauth2.resourceserver.jwt.issuer-uri is single valued and spring-boot provides with SupplierJwtDecoder or ReactiveJwtDecoder which are both designed to work with single issuer

Context

The company I currently work for has two different authorization-servers: one for intranet users and a different one for internet ones.

Some back-end services (resource-servers) are expected to provide data to users identified against either one or the other of the authorization-servers.

I came with following solution:

  • JwtDecoders for both servlet and reactive apps which map a SupplierJwtDecoder (or ReactiveJwtDecoder) for each issuer-uri. When it is asked to decode a JWT, it first extract iss claim from the payload and then delegates JWT validation and conversion to the right SupplierJwtDecoder (or ReactiveJwtDecoder)
  • Configuration aggregating issuer-uris (from spring.security.oauth2.resourceserver.jwt.issuer-uri and a private multi-valued property) and providing as JwtDecoder @bean, either this new JwtDecoder (if two or more issuers) or the former ones (no over-head for single issuer)

Notes:

  • yaml and properties files syntax would allow to turn spring.security.oauth2.resourceserver.jwt.issuer-uri into a string array while keeping backward compatibility
  • if you are interested and instruct me where and how, I'm ok to contribute some of the code I linked above
@ch4mpy ch4mpy added status: waiting-for-triage An issue we've not yet triaged type: enhancement A general enhancement labels Mar 8, 2022
@jzheaux
Copy link
Contributor

jzheaux commented Mar 8, 2022

Hi, @ch4mpy, thanks for the suggestion.

Have you already tried JwtIssuerAuthenticationManagerResolver? If so, what is making that approach not work? The reason multiple issuer support is at a higher level is so that the JwtAuthenticationConverter, etc. can also be keyed by the issuer URI.

@jzheaux jzheaux self-assigned this Mar 8, 2022
@jzheaux jzheaux added in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 8, 2022
@ch4mpy
Copy link
Contributor Author

ch4mpy commented Mar 8, 2022

@jzheaux thanks for quick answer.

No I had not tried JwtIssuerAuthenticationManagerResolver. To be totally honest I didn't know about it. But getting a quick look at it, it seems that it forces usage of JwtAuthenticationConverter which builds JwtAuthenticationTokens.

We do not use JwtAuthenticationToken but OidcAuthentication<T extends OidcToken> and thus have to configure a custom authentication converter.

Side note: turning spring.security.oauth2.resourceserver.jwt.issuer-uri into a String[] would ease the configuration of JwtIssuerAuthenticationManagerResolver too.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Mar 8, 2022
@jzheaux
Copy link
Contributor

jzheaux commented Mar 8, 2022

Makes sense. You can provide your own AuthenticationManagerss like so:

@Bean 
JwtIssuerAuthenticationManagerResolver byIssuer(MyJwtConverter converter) {
    Map<String, AuthenticationManager> managers = new HashMap<>();
    for (String issuer : issuers) {
        JwtDecoder decoder = new SupplierJwtDecoder(() -> JwtDecoders.fromIssuerLocation(issuer));
        JwtAuthenticationProvider provider = new JwtAuthenticationProvider(decoder);
        provider.setJwtAuthenticationConverter(converter);
        managers.put(issuer, provider::authenticate);
    }
    return new JwtIssuerAuthenticationManagerResolver(managers::get);
}

Agreed that changing to an array would simplify things. It's yet to be seen if multiple issuers is a common enough practice to merit adding to Boot. If you like, you can create a ticket in Spring Boot about it and then we can see if there are enough votes for it from the community.

@jzheaux jzheaux closed this as completed Mar 8, 2022
@jzheaux jzheaux added status: declined A suggestion or change that we don't feel we should currently apply and removed status: feedback-provided Feedback has been provided labels Mar 8, 2022
@jzheaux
Copy link
Contributor

jzheaux commented Mar 8, 2022

Also, #9096 may provide some helpful further reading about JwtIssuerAuthenticationManagerResolver and JwtAuthenticationConverter, if you are interested.

@ch4mpy
Copy link
Contributor Author

ch4mpy commented Mar 9, 2022

spring-boot ticket created

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants