Reputation: 1409
Let's say we have several micro-services. Each of them uses Keycloak authentication. We have also load balancer based on for ex. nginx which has external URLs and different routes to keycloak (for ex. in OpenShift it can be https://keycloak.rhel-cdk.10.1.2.2.xip.io). But internally this address can be inaccessible. Also having micro-service configuration dependent on the load balancer URL is a bit weird. What what be more appropriate is to use internal keycloak auth URL inside of the micro-services or even short URI. But in this case token will not be validated because of issuer validation problem. How to configure this in good and flexible manner? Can I simply override realmInfoUrl in order to change the validation? Can I define what issuer will be used for client based token.
Another problem is how to better handle multi-tenant scenario? First on the client side I guess we don't have any specific support for multi-tenancy. I should handle this manually by switching between different URLs/headers and use proper Config Resolver. On the server side I need to dynamically provide a proper KeycloakDeployment instance for each case. Any other recommendations?
Upvotes: 8
Views: 14113
Reputation: 41
In case this helps anyone out during the early stages of development, you can set the Host header to the keycloak url that your backend service will use during the validation of the token. This way, the generated token will contain your Host header url in the issuer field. In my sandbox, I had keycloak running on docker at keycloack:8080 and a functional test calling keycloack via localhost:8095 to request a token (direct grant). Before setting the Host header to keycloack:8080, the issuer field was being set to localhost:8095 and the token was failing the validation with the "Invalid token issuer" error, since the backend service connects to keycloak on keycloak:8080 and TokenVerifier.java does the following check.
public boolean test(JsonWebToken t) throws VerificationException {
if (this.realmUrl == null) {
throw new VerificationException("Realm URL not set");
} else if (!this.realmUrl.equals(t.getIssuer())) {
throw new VerificationException("Invalid token issuer. Expected '" + this.realmUrl + "', but was '" + t.getIssuer() + "'");
} else {
return true;
}
}
Reference: https://github.com/keycloak/keycloak-community/blob/master/design/hostname-default-provider.md
Upvotes: 3
Reputation: 3731
Unfortunately Keycloak is too restrictive with its token validation according to the issuer ("iss") field in the token. It requires that the URL used to validate the token matches the URL in the "iss" field.
A while ago I have opened a JIRA ticket for that problem (vote for it!): https://issues.jboss.org/browse/KEYCLOAK-5045
Upvotes: 7