Describe the bug
Using the latest Spring Boot snapshot version (2.5.0-SNAPSHOT) that has Spring Security 5.5.0-RC1 as dependency, a ClassCastException is thrown when creating a JwtDecoder from an issuer uri.
Caused by: java.lang.ClassCastException: class com.nimbusds.jose.Algorithm cannot be cast to class com.nimbusds.jose.JWSAlgorithm (com.nimbusds.jose.Algorithm and com.nimbusds.jose.JWSAlgorithm are in unnamed module of loader 'app')
at org.springframework.security.oauth2.jwt.JwtDecoderProviderConfigurationUtils.getSignatureAlgorithms(JwtDecoderProviderConfigurationUtils.java:93) ~[spring-security-oauth2-jose-5.5.0-RC1.jar:5.5.0-RC1]
It can be fixed by using
JWSAlgorithm jwsAlgorithm = JWSAlgorithm.parse(jwk.getAlgorithm().getName());
jwsAlgorithms.add(jwsAlgorithm);
instead of casting.
To Reproduce Start the app in the provided repository.
Expected behavior No errors on startup.
Sample https://github.com/tiborkoch/spring-security-oauth2resourceserver
Comment From: ubaid4j
I was testing latest Spring Boot snapshot version (2.5.0-SNAPSHOT) and I got the same above issue. Folllowing is the stacktrace: Spring Boot Version: 2.5.0-SNAPSHOT Spring Security Version: 5.5.0-RC1
Caused by: java.lang.ClassCastException: class com.nimbusds.jose.Algorithm cannot be cast to class com.nimbusds.jose.JWSAlgorithm (com.nimbusds.jose.Algorithm and com.nimbusds.jose.JWSAlgorithm are in unnamed module of loader 'app')
at org.springframework.security.oauth2.jwt.JwtDecoderProviderConfigurationUtils.getSignatureAlgorithms(JwtDecoderProviderConfigurationUtils.java:93) ~[spring-security-oauth2-jose-5.5.0-RC1.jar:5.5.0-RC1]
at org.springframework.security.oauth2.jwt.JwtDecoders.withProviderConfiguration(JwtDecoders.java:122) ~[spring-security-oauth2-jose-5.5.0-RC1.jar:5.5.0-RC1]
at org.springframework.security.oauth2.jwt.JwtDecoders.fromIssuerLocation(JwtDecoders.java:102) ~[spring-security-oauth2-jose-5.5.0-RC1.jar:5.5.0-RC1]
at com.ubaid.ms.countryservice.config.SecurityConfig.jwtDecoder(SecurityConfig.java:41) ~[classes/:na]
at com.ubaid.ms.countryservice.config.SecurityConfig$$EnhancerBySpringCGLIB$$7ab3f55b.CGLIB$jwtDecoder$0(<generated>) ~[classes/:na]
at com.ubaid.ms.countryservice.config.SecurityConfig$$EnhancerBySpringCGLIB$$7ab3f55b$$FastClassBySpringCGLIB$$70b6db75.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.6.jar:5.3.6]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.6.jar:5.3.6]
at com.ubaid.ms.countryservice.config.SecurityConfig$$EnhancerBySpringCGLIB$$7ab3f55b.jwtDecoder(<generated>) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.6.jar:5.3.6]
... 61 common frames omitted
Comment From: jgrandja
Thanks for the report @tiborkoch. I was able to reproduce the same issue with the provided sample.
The fix you suggested is correct. Would you be interested in submitting a PR for this fix?
Comment From: wsaca
@tiborkoch I didnt have enough time to fix this issue, but if you can do it I share with you the old issue.
Comment From: tiborkoch
@jgrandja @wsaca I'll do it, will try to submit the pr in a few days
Comment From: tiborkoch
Fixed in https://github.com/spring-projects/spring-security/pull/9658
Comment From: RobertHeim
Is there a workaround until the fix is released?
Comment From: jzheaux
Hi, @RobertHeim, yes, you can create the NimbusJwtDecoder instance directly, like so:
@Bean
JwtDecoder jwtDecoder() {
String issuerUri = ...;
String jwkSetUri = ...;
OAuth2TokenValidator<Jwt> validator = JwtValidators.createDefaultWithIssuer(issuerUri);
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwtSetUri(jwkSetUri).build();
jwtDecoder.setJwtValidator(validator);
return jwtDecoder;
}
Comment From: jzheaux
Or, if you are a Spring Boot application, then you can instead do:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://auth.example.org/issuer
jwk-set-uri: https://auth.example.org/jwks
Comment From: RobertHeim
Thanks for the fast feedback. That works!