spring-authorization-server: Incompatibility with Spring Security 5.6

Describe the bug I’ve recently updated spring boot (spring-boot-starter-parent) version from 2.5.6 to 2.6.1. Spring Boot starter parent contains a dependency to spring-security-oauth2-jose 5.6.0. When I request the access token, using the authorization code flow, I now get the following error

failed to access class org.springframework.security.oauth2.jwt.JoseHeader from class org.springframework.security.oauth2.server.authorization.authentication.JwtUtils (org.springframework.security.oauth2.jwt.JoseHeader and org.springframework.security.oauth2.server.authorization.authentication.JwtUtils are in unnamed module of loader 'app')

Stacktrace java.lang.IllegalAccessError: failed to access class org.springframework.security.oauth2.jwt.JoseHeader from class org.springframework.security.oauth2.server.authorization.authentication.JwtUtils (org.springframework.security.oauth2.jwt.JoseHeader and org.springframework.security.oauth2.server.authorization.authentication.JwtUtils are in unnamed module of loader 'app') at org.springframework.security.oauth2.server.authorization.authentication.JwtUtils.headers(JwtUtils.java:46) ~[spring-security-oauth2-authorization-server-0.2.1.jar:0.2.1] at org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeAuthenticationProvider.authenticate(OAuth2AuthorizationCodeAuthenticationProvider.java:174) ~[spring-security-oauth2-authorization-server-0.2.1.jar:0.2.1] at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.6.0.jar:5.6.0] at org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter.doFilterInternal(OAuth2TokenEndpointFilter.java:165) ~[spring-security-oauth2-authorization-server-0.2.1.jar:0.2.1] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar:5.3.13] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.0.jar:5.6.0] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) ~[spring-security-web-5.6.0.jar:5.6.0] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.6.0.jar:5.6.0] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.0.jar:5.6.0]

Code triggering the error JwtUtils - headers()

static Builder headers() { return JoseHeader.withAlgorithm(SignatureAlgorithm.RS256); }

The flow was correctly working when I had Spring Boot parent 2.5.6

To Reproduce spring-authorization-server 0.2.0 (or 0.2.1) spring-boot-starter-parent 2.6.1 authorization code, request an access token

Expected behavior the access token is correctly returned

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 4
  • Comments: 19

Most upvoted comments

Hi @jgrandja, I was actually replying to you that I came to the same considerations. I moved the security-oauth2-authorization-server before spring-boot dependency declaration inside my pom and with that it now works, since the classloader is loading the org.springframework.security.oauth2.jwt.JoseHeader from security-oauth2-authorization-server.

If you want to reproduce it I’ve committed a Maven version of the 3 samples here :

Go to http://127.0.0.1:8080 IMPORTANT: Make sure to modify your /etc/hosts file to avoid problems with session cookie overwrites between messages-client and default-authorizationserver. Simply add the entry 127.0.0.1 auth-server


To resolve the problem simply move the spring-security-oauth2-authorization-server dependency before spring-boot in the default-authorizationserver project.

Thanks a lot for your support! Best, Andrea

@andrea-pellegatta Spring Authorization Server is not compatible with Spring Security 5.6. With the recent 5.6 release, JwtEncoder was introduced in spring-security#9208, which resulted in this incompatibility since JwtEncoder also exists in this project.

FYI, our plan is to @Deprecate JwtEncoder (and associated classes) in this project and use the ones provided in Spring Security. This refactoring will happen in gh-594 and will resolve the incompatibility.

Spring Security 5.6 has the same class JoseHeader in the same package but it’s not public(but I think it should be public).

@andrea-pellegatta Although I wasn’t able to reproduce the issue, after inspecting the provided stack trace in detail and looking at the classpath of the default-authorizationserver sample, I’m very confident that this is a class loading issue.

The default-authorizationserver sample is a Spring Boot app, which produces a Fat Jar, and ensures the spring-security-oauth2-authorization-server dependency is ordered before the spring-security-oauth2-jose dependency. This is why I’m not able to reproduce the issue because the classpath order is correct.

What is likely happening in your setup is that the spring-security-oauth2-jose dependency sits before the spring-security-oauth2-authorization-server dependency in the classpath order resulting in the IllegalAccessError when the JVM attempts to load classes from both jars.

Are you able to share information of your setup? Are you using a Spring Boot Fat Jar? What is your classpath order? Are you able to change the classpath order?

The workaround to get this working with Spring Security 5.6+ is to change the classpath ordering to ensure spring-security-oauth2-authorization-server is before spring-security-oauth2-jose. NOTE: This is a temporary workaround until we release 0.3.0 (see gh-594).

This issue you’re experiencing is expected behaviour since Spring Authorization Server is built against Spring Security 5.5 and will not be compatible until we upgrade to Spring Security 5.6 (see gh-594).

If you’re using Spring Boot 2.6+, then you need to downgrade Spring Security to a 5.5.x release.

I’m going to close this since this is expected behaviour with Spring Security 5.6 and will be resolved in gh-594.

@bjornharvold

It seems that there is no way, we have downgraded to spring security 5.5.4, but still springboot 2.6.2, it seems worked!

configurations.all{
        resolutionStrategy.eachDependency {
            val request = requested
            if (request.group == "org.springframework.security" && request.module.name != "spring-security-oauth2-authorization-server") {
                this.useVersion("5.5.4")
            }
        }
    }

The only thing to be careful about is that this class is not compatible with spring boot 2.6:

@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingBean(JwtDecoder.class)
	static class JwtDecoderConfiguration

so you have to define JwtDecoder bean by yourself !