Support auto-configuration of an OAuth2 Resource Server that supports both JWTs and Opaque Tokens.
We have a use case where some of the OAuth2 Clients send JWTs to our OAuth2 Resource Servers, and some of them send Opaque Tokens.
Spring Boot 2.2.x currently supports auto-configuration of resource servers that only support JWTs or Opaque Tokens, but not both at the same time.
Spring-security can theoretically support both at the same time, if an ReactiveAuthenticationManagerResolver
were configured on the ServerHttpSecurity
. It would be great if spring-boot were able to support and possibly auto-configure this.
For example, the configuration below currently results in this error on startup:
ava.lang.IllegalStateException: Only one of jwt.issuer-uri and opaquetoken.introspection-uri should be configured.
at org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties.handleError(OAuth2ResourceServerProperties.java:68)
at org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties.validate(OAuth2ResourceServerProperties.java:59)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
I'd like to be able to use this configuration to configure both JWT and Opaque Token support:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://issuer/
opaquetoken:
introspection-uri: https://issuer/check_token
client-id: clientId
client-secret: clientSecret
The missing piece of the puzzle is how to differentiate a JWT from an Opaque Token. Perhaps a default implementation of this logic would be to try to decode the token as a JWT first, and if that fails, treat it is an Opaque Token. This logic would need to be customizable, however.
Comment From: mbhave
At first glance, this seems like something we could support. I'll take a look at it after the holidays.
Comment From: mbhave
My first thought was we'd just need to auto-configure an AuthenticationManagerResolver
but it seems like we'd need to implement one that would be able to authenticate both JWT and Opaque Tokens. I'm not keen on adding this logic to Spring Boot. At this point, I think it's better if the user configures their own SecurityWebFilterChain
(or WebSecurityConfigurerAdapter
for servlet applications). We could change our code to not fail if both jwt.issuer-uri
and opaquetoken.introspection-uri
are configured. We'd then have to decide which one to pick if both were configured and no SecurityWebFilterChain
was configured in the user's configuration.
@philsttr Would that work for you?
Comment From: philsttr
Yes, I think as long as the spring-boot auto-configuration...
1. did not fail if both spring.security.oauth2.resourceserver.jwt.*
and spring.security.oauth2.resourceserver.opaquetoken.*
properties were specified, and
2. still created both sets of beans defined in ReactiveOAuth2ResourceServerJwkConfiguration.JwtConfiguration
and ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.OpaqueTokenIntrospectionClientConfiguration
from the properties in (1)
...then the application could use the beans created by (2) to create a custom ReactiveAuthenticationManagerResolver
able to authenticate both JWTs and Opaque Tokens, and set the OAuth2ResourceServerSpec.authenticationManagerResolver
when configuring the ServerHttpSecurity
for the SecurityWebFilterChain
Comment From: philsttr
Thanks @mbhave !