spring-projects / spring-projects/spring-security

Spring Security Authorization Server NimbusJwtEncoder throws InaccessibleObjectException when refreshing token under native image

Open
#18,770 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage type: bug
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Describe the bug
I was testing refresh token under native image environment. The registered client's refresh token expiry time was set to 3600 seconds (1 hour) and session was set to 300 seconds. When session expires and I call the Spring Cloud Gateway with OAuth2.1 client token relay, I got the following:

com.nimbusds.jose.shaded.gson.JsonIOException: Failed making field 'java.time.Instant#seconds' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type. See https://github.com/google/gson/blob/main/Troubleshooting.md#reflection-inaccessible⁠ at com.nimbusds.jose.shaded.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:76) ~[na:na] at com.nimbusds.jose.shaded.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:388) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jose.shaded.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:161) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jose.shaded.gson.Gson.getAdapter(Gson.java:628) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jose.shaded.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:57) ~[na:na] at com.nimbusds.jose.shaded.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:222) ~[na:na] at com.nimbusds.jose.shaded.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:158) ~[na:na] at com.nimbusds.jose.shaded.gson.Gson.toJson(Gson.java:944) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jose.shaded.gson.Gson.toJson(Gson.java:899) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jose.shaded.gson.Gson.toJson(Gson.java:848) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jose.shaded.gson.Gson.toJson(Gson.java:825) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jose.util.JSONObjectUtils.toJSONString(JSONObjectUtils.java:547) ~[na:na] at com.nimbusds.jose.Payload.toString(Payload.java:363) ~[na:na] at com.nimbusds.jose.Payload.toBytes(Payload.java:395) ~[na:na] at com.nimbusds.jose.Payload.toBase64URL(Payload.java:412) ~[na:na] at com.nimbusds.jose.JWSObject.composeSigningInput(JWSObject.java:193) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jose.JWSObject.<init>(JWSObject.java:112) ~[org.example.mongodbtest.MongodbtestApplication:10.4] at com.nimbusds.jwt.SignedJWT.<init>(SignedJWT.java:60) ~[na:na] at org.springframework.security.oauth2.jwt.NimbusJwtEncoder.serialize(NimbusJwtEncoder.java:215) ~[na:na] at org.springframework.security.oauth2.jwt.NimbusJwtEncoder.encode(NimbusJwtEncoder.java:184) ~[na:na] at org.springframework.security.oauth2.server.authorization.token.JwtGenerator.generate(JwtGenerator.java:197) ~[na:na] at org.springframework.security.oauth2.server.authorization.token.JwtGenerator.generate(JwtGenerator.java:63) ~[na:na] at org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator.generate(DelegatingOAuth2TokenGenerator.java:60) ~[na:na] at org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationProvider.authenticate(OAuth2RefreshTokenAuthenticationProvider.java:248) ~[na:na]

Understand that it is mainly caused by Nimbus, but not sure if the Spring team can do something about it?

To Reproduce

  1. Create Authorization server with registered client's session set to 300 seconds and refresh token expires in 3600 seconds.
  2. Create Cloud gateway with oauth2 client token relay
  3. Create any rest API
  4. Create native image and deploy to docker
  5. Login and call the API
  6. Wait for 6 seconds
  7. Call the API again

Expected behavior
Token should be refreshed and API should be called successfully.

Sample
https://github.com/k6leung/MongoAuthServerTest

Reports that include a sample will take priority over reports that do not.
At times, we may require a sample, so it is good to try and include a sample up front.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Build and run the linked MongoAuthServerTest sample as a native image, using the listed refresh-token and session timings. Start by tracing NimbusJwtEncoder.serialize and encode through JwtGenerator.generate, then compare the refresh flow with the reported stack; done means the token refresh succeeds and the API call completes.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
authorization, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.