WSO2 Identity Server - Get Tenant ID in JWT - jwt

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()));

Related

Keycloak as IdP with own implementation of Resource Server

Is there a way of using Keycloak only to Authenticate user, but with own mapping to roles with Spring?
I would like to authenticate API Gateway in keycloak first, but then provide internal JWT Token with authorized roles inside my microservice world.
In this article, I do map Spring authorities from roles that Keycloak sets in JWTs. Is that what you are looking for?
If what you want is having a hand on access token claims, two cases:
the claim is already in the token but with a different value than what you expect (missing roles, outdated email, ...). Then, it is very likely that Keycloak admin API exposes what you need to update users data. Check that a "confidential" client with required roles is declared with client-credentials flow enabled (or declare a new one) and have relevent resource-server call admin API for updates (with WebClient, RestTemplate, #FeignClient or whatever is capable of using client-credentials flow).
the claim does not exist yet. Then, define a new Keycloak "mapper" to add a private claim. Here is a sample. You can have a look at security module to figure out how this new private claim is parsed (by ProxiesClaimSet) into an Authentication custom implementation.
In any case, the authorization-server (Keycloak) is the only place to define claims, issue JWT and sign it. JWT validation by JWT decoder on resource-server involves much more than just checking expiration date: issuer, issued-at, token integrity (server signs the payload with a private key and exposes a public one to ensure the token content was not modified), and more are verified too.
You want to make access control inside resource-servers? Great! Ensure that authorization header with Bearer access-token is forwarded by the gateway from client(s) to resource-server(s) and configure your resource-server(s) as described in the article above.
P.S.
In the article you'll also find a way to test security rules (both unit and integration) with mocked authentication. This is what, in my opnion, makes resource-server(s) a better place to implement access-control: security rules are of primary business importance and fine grained unit-testing is essential.
Other note, if you go for additional private claim(s) with Keycloak mapper(s), pay attention to pom.xml file, java/main/resources and implemented interfaces of ProxiesMapper into proxies-keycloak-mapper module.
Last, you should also follow the first 3 of those tutorials (for real: write the code and run the tests), it will take you less than an hour and will save you many more hours struggling with your resource-server(s) security implementation.

User ID attribute in JWT token to the backend WSO2 APIM

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"

Keycloak: Retrieving Attributes from JSON API after Authentication

Use case is client, SAML or OIDC, will authenticate users via Identity Provider (OIDC say Google; or SAML) - on return of authentication from the Identity Provider, Keycloak will call out to an external JSON API, to obtain further attributes on the user (say lookup by email for telephone number).
Is above possible? Any hints on how to approach will be greatly appreciated.
I was referencing keycloak-json-remote-claim/README.md at master · groupe-sii/keycloak-json-remote-claim · GitHub as an OIDC example – not sure if I’m in correct ballpark.
If you want to add additional user attributes from an external service you should:
Create your own auth flow
Create plugin with Authenticator and AuthenticatorFactory
Implement all logic in Authenticator
Add AuthenticatorFactory to the new flow
Assign new flow to your main client
After these steps your Authenticator will invoke external service and put all needed attrs to the user, each time when user logs in through your main client

Create my own AccessTokens with MS Identity Platform

I am in the process of expanding our login options on our product to support MS Identity Platform, to be able to use Azure AD login (and gain SSO/MFA with that)
Currently we are using .Net Core + JWT (JwtBearerDefaults.AuthenticationScheme)
The environment is angular clients, .Net Core APA, and a back-end database.
I have the setup working.
My challenge is that in our business model and backend database we have ~2.000 userrights and our own User/Role model granting access.
I am currently getting the IdToken from MSAL and in my proof of concept using the oid to couple the Azure ID with our User model.
But, in our existing JWT solution, our access token holds claims about the User Id, but also the role, and another property (Unit/Vessel) determining access. From these three properties we can verify against the 2.000 userights on API side whether or not a request is allowed or not.
I would like to keep this information (User, Role, Unit) in the token - but have doubts on how.
Constraints:
We cant create/use Azure claims. We have too many, and customers will manage the Azure application - while we create, add, remove rights for each version of our software.
Azure don't know about role/unit data - and these are different for each customer - so that information can't be in Azure either.
My best idea is outlined below - would this approach be correct, and live up to the way ID/Access is separated?
I hope someone can give me some feedback on this.
My idea is, that the Angular client gets the Azure IDToken. I then use the Azure IDToken, call our API, which on server side, validates ID Token, and then grants me an access token, which contains the user, role and unit. This token is not Azure'd at all, just a token generated by our API - which again will be the only one validating it). Pro's on this approach is also I can keep one type of Access Token, no matter which IDToken is supplied by Azure or our own API.
Tried to outline the flow below in this DrawIO diagram.
I hope someone with more experience in the Token field can validate if this would be a viable approach?
Best regards
/Anders
This is a viable approach except for one thing.
Do not use Id token for authorization.
Your front-end should acquire an access token from AAD for your back-end.
This access token contains the user objectId, allowing you to map the user to a user in your database.
An Id token is only meant for the application that requested authentication and tells it metadata on the user like their display name etc., but it is not meant for authorizing anything.

AWS API Gateway with cognito authorization

Currently I'm developing serverless architecture where there are set of resources and methods in AWS API gateway. I plan to add Cognito authentication(user pool) and authorization as secure layer to AWS API gateway.
There are 3 authorizer in AWS API Gateway which are IAM, Cognito User Pool and custom lambda.
For my use case, the sign-in and sign-up(authentication) are using cognito user pool via API gateway. It's perfect works. My user will given app client id and client secret to enable both processes. Once after sign-in, my intention is get user able to use the access token(returned by user pool) to access resource via api gateway.
However, my user can has different role such admin, owner or guest. User only can access the authorized api. My approach is to put user into different group in user pool, assign IAM policy to group and enable identity pool. This force me to change the authorization type in api gateway to IAM. and IAM require every request to be signed by Signature V4.
It means every requests have to sign up by session token, access key, secret (returned after exchange id token with federated pool) instead of using access token based approach. So in my use case, after my user sign-in via api gateway, my client app(web/mobile/postman tool) has to generate signature and put in Authorization header. Is there alternative ways to control authorisation in user pool group but using access token in api gateway? My understanding is access token (in Authorization header) is much easier to use than complex signed signature process.
Correct me if I'm wrong. Thanks.
Will this help instead?
Create groups in user pool and assign IAM role to the group.
And then add users to the group.
More documentation here: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-user-groups.html
You are on the right track but you have chosen one of the paths of Authorizing the user requests on AWS. You are using IAM and Identity Pool and because of that, you are forced to sign every request using Signature V4 provided by AWS.
Instead of going for I would suggest as per my experience to choose custom Lambda Authorizer over Identity Pool. In this case, your authentication will remain as it is that you have already built. But instead of applying IAM as Authorizer in API gateway, you can create a lambda function that will receive the ARN of the API gateway that the user wanted to authorize in the request and user ID_TOKEN that you received in during authentication from User Pool.
{
...
"cognito:roles": [
"arn:aws:iam::**********:role/addBookSellerRole"
],
"exp": 1565758916,
"iat": 1565755316,
...
}
You can see you will get the roles array from the ID_TOKEN in JWT received from authentication. You can use this role to fetch the attached policies to this role. Follow this document to fetch the policies from the role.
Once you get the policy JSON you can compare it with the ARN of the method received in request with the list of policies. And this way you have to generate a Policy Document that will either Allow or Deny the request.
To read more about it visit my medium blog Authorization using Cognito + API Gateway + IAM.