generator-jhipster: JWT decoding failure when upgrading from 7.8.1 to 7.9.0

Overview of the issue

I was working on upgrading a monolith oauth2 app from 7.8.1 to 7.9.1.

We currently use Keycloak 15.1.1.

When trying to call any services from our React app I am getting 401s.

After examining the response headers, I see:

WWW-Authenticate: Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: timestamps must be of type Instant: java.util.Date", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"

I manually decoded the JWT and iat and exp seem fine:

  "exp": 1659374140,
  "iat": 1659373840,

It looks like something in nimbus is converting them to java.util.Date instead of Instant.

Is anyone else seeing this issue?

Motivation for or Use Case

This should work out of the box.

Reproduce the error
Related issues
Suggest a Fix

As a work around, I manually converted the iat and exp claims to Instant in CustomClaimConverter:

    public Map<String, Object> convert(Map<String, Object> claims) {
    	LinkedHashMap<String, Object> tempClaims = new LinkedHashMap<String, Object>();
    	for (String key : claims.keySet()) {
    	    Object value = claims.get(key);
    	    if (key.equals("exp") || key.equals("iat")) {
    	        value = ((Date) value).toInstant();
    	    }
    	    tempClaims.put(key, value);
    	}
        // Only look up user information if identity claims are missing
        if (tempClaims.containsKey("given_name") && tempClaims.containsKey("family_name")) {
            return tempClaims;
        }
        Map<String, Object> convertedClaims = this.delegate.convert(tempClaims);
JHipster Version(s)
test-app@0.0.0 /Users/jmillard/git/test-app
└── generator-jhipster@7.9.0

JHipster configuration, a .yo-rc.json file generated in the root folder
.yo-rc.json file
{
  "generator-jhipster": {
    "applicationIndex": 0,
    "applicationType": "monolith",
    "authenticationType": "oauth2",
    "baseName": "TestApp",
    "blueprints": [],
    "buildTool": "gradle",
    "cacheProvider": "ehcache",
    "clientFramework": "angularX",
    "clientPackageManager": "npm",
    "clientTheme": "none",
    "clientThemeVariant": "",
    "creationTimestamp": 1609459200000,
    "databaseType": "sql",
    "devDatabaseType": "h2Disk",
    "dtoSuffix": "DTO",
    "enableGradleEnterprise": false,
    "enableHibernateCache": true,
    "enableSwaggerCodegen": false,
    "enableTranslation": true,
    "entities": ["LastSeq"],
    "entitySuffix": "",
    "gradleEnterpriseHost": "",
    "jhiPrefix": "jhi",
    "jhipsterVersion": "7.9.0",
    "languages": ["en"],
    "lastLiquibaseTimestamp": 1609459260000,
    "messageBroker": false,
    "nativeLanguage": "en",
    "otherModules": [],
    "packageFolder": "com/testapp",
    "packageName": "com.testapp",
    "pages": [],
    "prodDatabaseType": "postgresql",
    "reactive": false,
    "searchEngine": false,
    "serverPort": "8080",
    "serviceDiscoveryType": false,
    "skipCheckLengthOfIdentifier": false,
    "skipClient": true,
    "skipFakeData": true,
    "skipUserManagement": true,
    "testFrameworks": [],
    "websocket": false,
    "withAdminUi": true
  }
}
JDL for the Entity configuration(s) entityName.json files generated in the .jhipster directory
JDL entity definitions
entity LastSeq {
  id UUID
  startSeq Long required
  endSeq Long required
  createdAt Instant
  lastUpdate Instant
}
paginate LastSeq with pagination

Environment and Tools

openjdk version “18.0.1.1” 2022-04-22 OpenJDK Runtime Environment Homebrew (build 18.0.1.1+0) OpenJDK 64-Bit Server VM Homebrew (build 18.0.1.1+0, mixed mode, sharing)

git version 2.36.1

node: v16.16.0

npm: 8.11.0

Docker version 20.10.17, build 100c701

Docker Compose version v2.6.1

Browsers and Operating System

MacOS 12.4 Chome 103.0.5060.134

  • Checking this box is mandatory (this is just to show you read everything)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 3
  • Comments: 42 (38 by maintainers)

Most upvoted comments

I am also getting the exact same error (401) and message after upgrading from 7.8.1 to 7.9.0. We are using the Keycloak version: 15.0.2. Frontend is vue app

I’m not sure we need to adjust our default Keycloak config because we don’t expect people to use it in production. In fact, we don’t even generate Keycloak files for Kubernetes.

I do think it would be useful to create (or link to) a guide for hardening and configuring Keycloak in production.

@gmarziou Because access tokens are only meant for authorization and can be opaque (a random string of characters, and not a JWT), as specified by the OAuth 2.0 spec. ID tokens are where identity information belongs. That’s why we switched from looking for ID information in the access token to looking it up from /userinfo when it wasn’t available.

Screen Shot 2022-08-05 at 8 22 43 AM

Here’s a little bit of the stack trace right at the CustomClaimConverter.