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)
- 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.0Import keycloak realm from quickstart example - 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 - 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'
- 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)
I had the same problem and solved it by entering the Realm settings -> General -> Frontend URL
https://<your-container-name>:<port>for examplehttps://keycloak:8443Reason: 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
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:adminas described in theTesting section- but replacehttps://localhost:8543withhttp://localhost:8180/, and forward the token to the endpoint - you’ll get401- because the endpoint is configured to work over HTTPS - so it is fixed by addingquarkus.oidc.token.issuer=any, resend the token and you’ll see: