quarkus: Keycloak authorization: "Invalid identity" (userId=null)

Describe the bug

Trying the security-keycloak-authorization-quickstart, there is a problem when running in a containerized environment (Kubernetes or even single node docker installation). The retreived access token is not working and I see the following log outputs when running both Keycloak and quickstart application running in containers.

Keycloak log:

WARN  [org.keycloak.events] (default task-6) type=PERMISSION_TOKEN_ERROR, realmId=quarkus, clientId=backend-service, userId=null, ipAddress=10.12.1.3, error=invalid_token, reason='HTTP 500 Internal Server Error', auth_method=oauth_credentials, audience=backend-service, grant_type=urn:ietf:params:oauth:grant-type:uma-ticket, permission=df1b74a9-3f10-499d-a581-368de48e512b, client_auth_method=client-secret

Authorization quickstart example log:

Authorization failed: java.lang.RuntimeException: org.keycloak.authorization.client.util.HttpResponseException: Unexpected response from server: 400 / Bad Request / Response from server: {"error":"unauthorized_client","error_description":"Invalid identity"}
...

The userId=null is probably the culprit, but why is it null in the first place?

Running only Keycloak in a container and the REST application on the host machine with the quarkus-app.jar file, the example is working as expected (even with the same access token retrieved from Keycloak).

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

Build quickstart example container image with additional dependency quarkus-container-image-docker and property quarkus.container-image.build=true.

On a host machine with docker installation (+quarkus network)

  1. Start Keycloak in a container with docker container run -d --name keycloak -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -e DB_VENDOR=H2 --network quarkus -p 8080:8080 jboss/keycloak:15.0.2 -b=0.0.0.0 Import keycloak realm from quickstart example
  2. Start quickstart example container with docker container run -d -e QUARKUS_OIDC_AUTH_SERVER_URL="http://keycloak:8080/auth/realms/quarkus" -e QUARKUS_OIDC_TOKEN_ISSUER="http://localhost:8080/auth/realms/quarkus" --network quarkus -p 8081:8080 quarkus/security-keycloak-authorization-quickstart:1.0.0-SNAPSHOT
  3. Get user access token
curl -L -X POST 'http://localhost:8080/auth/realms/quarkus/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=alice' \
--data-urlencode 'password=alice' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=backend-service' \
--data-urlencode 'client_secret=secret'
  1. Request user endpoint curl -L -X GET 'http://localhost:8081/api/users/me' -H 'Authorization: Bearer <retrieved-access-token>'

When running the quickstart example jar file directly on the host (QUARKUS_HOST_PORT=8081, accordingly) with the same Keycloak container instance, the authorization is working.

Output of uname -a or ver

No response

Output of java -version

No response

GraalVM version (if different from Java)

No response

Quarkus version or git rev

No response

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

We observed the problem with one of our own REST services when trying to enable authorization. After some investigation I was able to reproduce the same behavior with the keycloak authorization quickstart example version 2.2.1.Final. I tested with images of Keycloak 14.0.0 and 15.0.2 with the same result.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 22 (11 by maintainers)

Most upvoted comments

I had the same problem and solved it by entering the Realm settings -> General -> Frontend URL https://<your-container-name>:<port> for example https://keycloak:8443

Reason: I issued my tokens with Postman using localhost so the token issuer was localhost. But internally the backend referenced keycloak by container name keycloak, so I got following error

DEBUG [org.keycloak.services.managers.AuthenticationManager] (executor-thread-13) 
Failed to verify identity token: Invalid token issuer. Expected 
'https://keycloak:8443/realms/quarkus', but was 'https://localhost:8443/realms/quarkus'

After changing the frontend url, the token request’s base url gets overriden and that fixed my problem.

@pedroigor Hi Pedro - the same problem can be easily reproduced without the docker, simply start Keycloak server as described in the guide (both HTTP 8180 and HTTPS 8543 ports are available) - then use a curl command to request a token for admin:admin as described in the Testing section - but replace https://localhost:8543 with http://localhost:8180/, and forward the token to the endpoint - you’ll get 401 - because the endpoint is configured to work over HTTPS - so it is fixed by adding quarkus.oidc.token.issuer=any, resend the token and you’ll see:

16:26:48,991 WARN  [org.keycloak.events] (default task-3) type=PERMISSION_TOKEN_ERROR, realmId=quarkus, clientId=backend-service, userId=null, ipAddress=172.17.0.1, error=invalid_token, reason='HTTP 500 Internal Server Error', auth_method=oauth_credentials, audience=backend-service, grant_type=urn:ietf:params:oauth:grant-type:uma-ticket, permission=7124e2f1-e6dc-44b4-87ab-24b010090b97, client_auth_method=client-secret