I'm using keycloak as my user management and trying to generated jwt to be used in other microservices, and as i understand to add new filed or info to the jwt, i need to create new client scope then link it to predefine mapper to be included in the jwt but i can't find any predefined realm id mapper, so is their any other way to add the realm id to the jwt ? or I'm messing something from the predefined mapper?
I'm using keycloak version 19.0.1
Related
I have some questions regarding the Quarkus oidc extension for validating access to a service (not an oidc client, so I am not calling OIDC flows, only validating tokens):
In addition to validating the JWT access token (authorization bearer token), is it possible to validate the id token, defined in another header? (in my case x-id-token)
Would additional claims in the ID token be accessible somehow, for example through SecurityIdentity or something else?
I would like to avoid having to call the userInfo endpoint every time.
Also, in my case, the id token contains "groups", that I would have liked to be mapped to roles to be used in #RolesMapping: is this possible? In Microprofile JWT, for non-OpenID Connect cases, it seems like the groups claim is defined on the access token, but in OIDC from my interpretation, it seems logical that this kind of information is on the id token, isn't it?
I tried adding "quarkus.oidc.roles.source=idtoken" on my app, but this seems to be limited to oidc client applications.
Also, perhaps it's just me, but I am confused by the doc for OIDC for services (https://quarkus.io/guides/security-openid-connect), regarding what is client OIDC and what is server-side validation for services: this page seems to be focused on services, but then the configuration part references a lot of configuration properties that concern client applications that must call the OIDC endpoints, OIDC flows, etc. Am I missing / misunderstanding something?
(Note: otherwise the extension is great! And multi-tenancy is very useful…and is also the first reason why we initially preferred using this extension instead of the Quarkus Smallrye JWT)
Thank you.
I'm having trouble implementing the following use case. I need to pass the User ID claim to the backend. I've enabled enable_outbound_auth_header so that the token I get from the application arrives to the backend. I've managed to add the User ID to this token. I want to use JWT grant, Code grant, client credentials grant and APIKey. However, User ID is only added to the token on code and JWT grants. The way I did it was using OIDC scopes.I've seen in docs that I can use apim.jwt to pass enduser attributes, however I haven't managed to pass User ID. Is there any way to achieve this? (without custom generators)
In the case I have to implement a custom token generation I'm wondering which one to
implement. I've seen that there are many possibilities. Should I implement a token generator? Will this one work for apiKey token? I think there are at least four possible toke generators (gateway token generator, jwt token generator, oauth token generator and oidc token generator. Which one or how many should I implement?
I ended up implementing two custom token generators. I just inherited from the default class implementation for each generator and added the userId claim. Then I added them in the deployment.toml
For the apikey generator (extended DefaultApiKeyGenerator) simply added
[apim.devportal]
url = "https://localhost:9443/devportal"
api_key_generator_impl = "com.apikeygenerator.CustomAPIKeyGenerator"
The other one I implemented was the oauth token generator (extended JWTTokenIssuer). Adding this one to the configuration using
[[oauth.extensions.token_types]]
name = "JWT"
issuer = "com.oauthjwtgenerator.CustomOauthJWTGenerator"
I'm trying to validate (and read roles from) a JWT Token. Sadly I can't use any adapter or auto configuration due to my overall application architecture.
It's no problem to decode the token like any other JWT Token, but I wonder if there is a library from Keycloak to archive this goal. (For example Just Parse the token to something like a KeycloakJWTToken and verify it by grabbing the secret from Keycloak Server or so)
Any easy-to-use client or so?
I'm using the Jose4J library:
https://bitbucket.org/b_c/jose4j/wiki/Home
Reading the claims inside a JWT token is straightforward:
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
public void parseJWT(String token) throws Exception {
JwtConsumer consumer = new JwtConsumerBuilder()
.setSkipAllValidators()
.setDisableRequireSignature()
.setSkipSignatureVerification()
.build();
JwtClaims claims = consumer.processToClaims(token);
System.out.println("* Parsed token: "+ claims.getRawJson() );
System.out.println("* Expiration date: " + new Date(claims.getExpirationTime().getValueInMillis()) );
}
More examples are available on GitHub:
https://github.com/pvliesdonk/jose4j/blob/master/src/test/java/org/jose4j/examples/ExamplesTest.java
Last remark: you do not need a key nor a secret to parse the JWT, but if needed, you can use the server (public) key to verify the token was signed by the keycloak server you are trusting.
The JWT website is listing all libraries for Token Signing/Verification:
https://jwt.io/#libraries-io
Keycloak access tokens are indeed JWT tokens. So, you can make full use of existing JWT libraries, including for validation as stated in the Keycloak official documentation:
If you need to manually validate access tokens issued by Keycloak you can invoke the Introspection Endpoint. The downside to this approach is that you have to make a network invocation to the Keycloak server. This can be slow and possibily overload the server if you have too many validation requests going on at the same time. Keycloak issued access tokens are JSON Web Tokens (JWT) digitally signed and encoded using JSON Web Signature (JWS). Because they are encoded in this way, this allows you to locally validate access tokens using the public key of the issuing realm. You can either hard code the realm’s public key in your validation code, or lookup and cache the public key using the certificate endpoint with the Key ID (KID) embedded within the JWS. Depending what language you code in, there are a multitude of third party libraries out there that can help you with JWS validation.
Besides, in Java EE, using the Keycloak Java adapter, the roles are typically mapped on the user Principal and i.e. allows isUserInRole(). That's one of the goals.
Also it is possible to cast the Principal from the SecurityContext as a KeycloakPrincipal, then obtain in turn a KeycloakSecurityContext from it. Using the KeycloakSecurityContext you have access to both ID and Access tokens (when applicable) and can read their properties, attributes and claims.
Note that it is also good practice, and simply useful, to use the Keycloak UI to "evaluate" your tokens. For instance, you can see the generated token in the Client Scopes tab (under Evaluate), as well as evaluate your policies and permissions in the Authorization tab of your Client(s) (under Evaluate).
Cf. https://www.keycloak.org/docs/latest/server_admin/#_client_scopes_evaluate
That's probably the best way to debug and test, while setting up your Client(s).
If you select a user in the Evaluate screen, the following example data is generated:
Generated Access Token (...)
Generated ID Token (...)
Generated User Info (...)
All examples are generated for the particular user and issued for the particular client, with the specified value of scope parameter. The examples include all of the claims and role mappings used.
Source: https://www.keycloak.org/docs/latest/server_admin/#generating-example-tokens-and-user-info
Refer to this link I can add Tenant Domain Name information to our JWT token in sub like username#carbon.super
But I need a way to put Tenand ID info in JWT like a claim. How can I do this for IS 5.10.0 ?
It is not supported by IS OOTB. But you can write a custom claim provider sample and deploy it into the Identity Server. Refer this sample to know how to write a custom claim provider. https://github.com/wso2/samples-is/tree/master/etc/custom-claim-provider.
if it is authorizationcode grant or refresh token grant flow,
Refer this implementation https://github.com/wso2/samples-is/blob/master/etc/custom-claim-provider/src/main/java/org/wso2/carbon/identity/custom/claim/provider/CustomClaimProvider.java#L57 and
additionalClaims.put("tenantName", oAuthTokenReqMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain());
additionalClaims.put("tenantId", OAuth2Util.getTenantId(oAuthTokenReqMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain()));
If it is an implicit granttype or hybrid flow, then refer this and
https://github.com/wso2/samples-is/blob/master/etc/custom-claim-provider/src/main/java/org/wso2/carbon/identity/custom/claim/provider/CustomClaimProvider.java#L44
additionalClaims.put("tenantName", oAuthAuthzReqMessageContext.getTenantDomain());
additionalClaims.put("tenantId", OAuth2Util.getTenantId(oAuthAuthzReqMessageContext.getTenantDomain()));
We are building an application where multiple clients can register and have their own user bases. For example a client "CompanyA" can register and then allow their users to access to our system with their own usernames (some from LDAP). "CompanyB" can also do the same, the usernames will be unique for one client but can be duplicated across clients.
We are using keycloak for this and have used the concept of realms to achieve this. When a new client registers we create a new realm for them and do the required configurations. This works as expected but we are having issues with our middleware.
Our middleware is Kong which has an OIDC plugin which we integrate with keycloak, however the plugin requires the realm name which in our case is actually going to be dynamic.
For example:
When a user signs in from our UI he receives a token from their client's realm. Now when a user requests a resource from our backend, this request will go through kong.
Kong will introspect this token using its configured client and realm, however this cannot be selected dynamically so ideally I would want to have a configured client on the master realm for each client realm and use this magic client to introspect their tokens.
Is something like this possibel? If not what other avenues can I look into?
You can inspect the Access Token to see from which realm it was created.
If you decode the JWT token with something like https://jwt.io/ you will see a property on the token called issuer. That is the url of the realm that created the token.
So to get the realm, you do something like this:
import org.keycloak.TokenVerifier;
import org.keycloak.representations.AccessToken;
...
AccessToken token = (AccessToken)TokenVerifier.create(tokenString,
AccessToken.class).parse().getToken();
String realm = token.getIssuer().substring(token.getIssuer().lastIndexOf(47) + 1);