Minimal jwt token payload with keycloak - jwt

At my company, we are trying to use Keycloak to generate a jwt token with an minimal payload with only the role of the user, the email et the expiration of the token.
We need to use this minimal payload because we have a performance limitation I do not wish to explain further.
Is it possible? and how?
We are using Keycloak v7.0.0 and tried different things with the mappers to expose only what we need without success.
Edit: By removing everything in default scope, I still get a lot I do not need
{
"jti": "ac6f9ed1-e33b-4204-affc-c5992c600ead",
"exp": 1571741519,
"nbf": 0,
"iat": 1571741219,
"iss": "http://keycloak:8080/auth/realms/test",
"sub": "c530d809-fabf-44a7-b186-1d095321edf7",
"typ": "Bearer",
"azp": "web_app",
"auth_time": 0,
"session_state": "83ce24ff-9e2f-4775-ae2c-066935b7ffa9",
"acr": "1",
"scope": "openid"
}
I would like a payload that looks like this
{
"exp": 1571741519,
"email": "john#doe.com"
"groups": ["ROLE_USER"]
}
I am looking into adding a authenticator SPI

You should remove everything except role and role_list from Default Client Scopes.

By adding a script mapper, we can remove a lot of info from the payload.
token.setIssuer(null)
removes iss key
token.notBefore(null)
set nbf key to 0
You can look at the token JavaDoc for more information on what is possible to change.

Related

Removing cognito:username on AWS Cognito JWT Response

I am using AWS Cognito to conduct authentication. And, I am trying to figure-out if it's possible to remove one of JWT's key, value?
cognito:username
A typical decoded JWT would contain.
{
"sub": "aaaaaaaa-bbbb-cccc-dddd-example",
"aud": "xxxxxxxxxxxxexample",
"email_verified": true,
"token_use": "id",
"auth_time": 1500009400,
"iss": "https://cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_example",
"cognito:username": "exampleuser",
"exp": 1500013000,
"given_name": "Anaya",
"iat": 1500009400,
"email": "exampleuser#example.com"
}
Based here: https://aws.amazon.com/premiumsupport/knowledge-center/decode-verify-cognito-json-token/
I wanted to remove on the accessToken the cognito:username.
Just checking options if it's possible to remove or hide via cognito first, my last option would be using the code, meaning, parse it, then remove, then encode again.
Thanks
cognito:username cannot be removed or modified.
Ref: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html

How long is JWT time to live without "exp" field?

How long is JWT time to live without "exp" field? For example, this token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
does not have "exp". How long before it's updated, or will this token not be updated in my application?
When there's is no expiration time defined, the token won't expire. Then it would be valid until you change the secret that was used for signing and validation.
Of course you can also implement a mechanism based on the issued at (iat) claim and not accepting a token of a certain age, but this depends on your own implementation.

When to use Realm roles in Keycloak?

I'm experimenting with role mappings among microservices & frontends (keycloak-clients in Keycloak terms).
Let's suppose I have two keycloak clients:
routemanagement-api
routemanagement-webapp
In the routemanagement-api I'd define some roles, let's say one of them: regular-user . This role is not composite role.
In the routemanagement-webapp, I'd define another role, also named regular-user. This is a composite role. I'd associate it with the "regular-role" user in the routemanagement-api.
Then, I create a user. Let's suppose this user registers through routemanagement-webapp. So, my registration logic will assign "routemanagement-webapp:regular-user" role to this newly created user.
Since "routemanagement-webapp:regular-user" is associated with "routemanagement-api:regular-user" role, calls to routemanagement-api REST endpoints will succeed.
You see, I don't need realm (upper-level) roles to make that happen. I can jump from one client to another client directly. I'd say my approach is a top-down approach; the frontend apps at the top, the apis at the bottom. I'm thinking of having separate webapp for provisioning users. User will be granted roles to "webapps" she is allowed to use. The correct permissions to use associated apis are handled in the keycloak UI, by those composite-roles trick.
What do you think of that approach? Is it a correct way of thinking? And what do we need realm roles for?
I'd suggest you might not need the composite role. In my view, the api owns the resource so you should design your client roles as the api as the api client as the resource owner. The role could be named "verb-resource", e.g. "create-x, read-x, update-x, delete-x".
Even if you're authenticating using routemanagement-webapp client you can still infer the resource roles of the user for the routemanagement-api.
EXAMPLE JWT
{
"jti": "0ba58a94-d98e-4f29-abfa-ade95d96a62b",
"exp": 1589264282,
"nbf": 0,
"iat": 1589263982,
"iss": "http://localhost:8080/auth/realms/master",
"aud": "routemanagement-webapp",
"sub": "50b6d1f7-88ea-451c-92bb-fc7f5fcc6683",
"typ": "Bearer",
"azp": "routemanagement-webapp",
"auth_time": 0,
"session_state": "7a270756-917b-4afc-a06d-054b05e6d41a",
"acr": "1",
"allowed-origins": [],
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"routemanagement-api": {
"roles": [
"manage-regular-stuff"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"name": "Test User",
"preferred_username": "test.user",
"enabled": true,
"email": "test.user#test.com"
}
If you wanted To get more granular your could use the authorization and resource registration instead of the role based "verb-resource" naming strategy.

Forbidden !! while trying to access the hereapi traces service

I've been working on here API from past one week, I've tested the geofencing and other rest services. I am trying to work on tracking, Where we have to generate a token by giving all the valid credentials. At last, I've got the token as well but when am trying to access the traces one for which the endpoint URL is
https://tracking.api.here.com/traces/v2/{trackingid}
here I've given the trackingid(deviceid) which I've used to generate an access token and included this token as a bearer in authorization I am using postman to test these, my token is valid for only 23 hours
Authorization Bearer {mytoken}
As mentioned I've also provided this x-request-id, I've no idea regarding this x-request-id but came to know about this from this thread and tried to generate uuid and use it for x-request-id
x-request-id 5506b7d0-2fe6-4967-8ad8-cf0f08fdedbf
And I am receiving the response as
{
"code": 403,
"id": "5506b7d0-2fe6-4967-8ad8-cf0f08fdedbf",
"message": "Forbidden",
"error": "Forbidden\n\nThe account does not have the correct
privileges\n"
}
The similar case even when I am trying to access the allotted geofences for that device and how many devices are in that particular geofence. I've read about whitelisting but whatever the service I am requesting for is not on their list. My account was a 90days free trial account
I am new to this hereapi Kindly correct me if I am doing anything wrong.
Kindly Help me out with this issue
Thanks in advance
--Meghana Goud
I've figured it out, I'll include the details here follow the step by step process as mentioned in the documentation
refer this HERE Tracking | API Reference
And follow the step by step process as mentioned in this documentation
The first one, you'll get your bearer token from this endpoint URL https://tracking.api.here.com/users/v2/login which is post
method and set its Content-Type to application/json and provide the username and password in JSON format and send a POST request to it
EndpointURL :https://tracking.api.here.com/users/v2/login
Headers :{"Content-Type":"application/json"}
Input :{"email":"XXXXXX", "password":"XXXX"}
Expected Response:{
"userId": "XXXXXX",
"accessToken": "XXXXX",
"tokenType": "bearer",
"expiresIn": 86399,
"refreshToken": "XXX"
}
the token is valid for only 24 hours. Now use this token for all the rest services you want to access from here-API
Now I would like to get the traces of my device using this endpointURL https://tracking.api.here.com/traces/v2/{trackingid}?count=1 , send a get request to this endpointURL by giving your trackingID, I repeat TrackingID is different from your deviceId TrackingId will be HERE-XXX(UUIDv4) whereas deviceId will be XXXX(UUIDv4)
now set the authorization to Bearer Token and pass an x-request-id which is a UUIDv4
Your request should look like
EndpointURL :https://tracking.api.here.com/traces/v2/{trackingid}?count=1
Headers :{"Authorization":"Bearer XXXXXX","x-request-id":"XXXX(UUIDv4)"}
Expected Response:{
"count": 1,
"data": [
{
"position": {
"lat": 17.44936354,
"lng": 78.36296417,
"accuracy": 45,
"alt": 539
},
"timestamp": 1531462419813,
"payload": {
"refAppData":
{
"batteryState": {
"charging": false,
"level": 52,
"temperature": 25
}
}
}
}
],
"pageToken": "1531462359711"
}
In order to update any data from your device, you'll require your device token which is generated from this endpoint URLhttps://tracking.api.here.com/v2/token you'll get your access token by OAuth1.o Authorization give the respected values as mentioned in the documentation. you'll get the response as
{
"accessToken": "XXXXXX",
"expiresIn": 86399
}
Similarly, you can test other services,
Hope this helps
Meghana

Understanding the JWT signature in a signed token from IdentityServer

I'm essentially doing something very similar to this post. I would like to be able to verify some JWT tokens that have been signed on an IdentityServer, and there are a few details that I haven't figured out yet. Here is an example token:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjBiZjM5OWIwYjRkNzY3OTE5MDFlYzlmNTUxNTZkMzdlIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1Mjc4OTA2MDAsImV4cCI6MTUyNzg5NDIwMCwiaXNzIjoiaHR0cDovL2NvbW1hbmRjZW50ZXI6NTAwMCIsImF1ZCI6Imh0dHA6Ly9jb21tYW5kY2VudGVyOjUwMDAvcmVzb3VyY2VzIiwiY2xpZW50X2lkIjoiY29tbWFuZGNlbnRlciIsInN1YiI6ImU3NzY4MjEyLTdhMGYtNDA4YS04YzlmLWZmNDRmOTVlNzc2ZSIsImF1dGhfdGltZSI6MTUyNzg5MDYwMCwiaWRwIjoibG9jYWwiLCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIl0sImFtciI6WyJwd2QiXX0.N6j_8Mbc-WAZInLnhauBS_dC6my3ggJEFGNBuuanJXGG5Q1mL7K9KZ11cgxrWQEp6NRS07bZrh02qA0Hcd0pLJzg0xB49CR-kFlA8PWdZ-wnf1U4VGq7ZZY2PaxccqextF-s3V-ObEsnPq7k1csTBM_lBW5u4m907q3zcHfPtW9RNz3kELKSuW1vMOWksrOOaJO3UGAPJgRcFjlc5imPykKQVCiAO9UV1nuNUHOLOu4XDim-f3YHLU24J-vbgxkqdUtgs4Xm43b3AplYrkN_TJ0ba5demtnQNd5No0s6bkqkuPvVGz2G3MD5tWkQVnu7kV7GNfTOvJlInCkDOE6few
Taking this over to https://jwt.io/ you can see that the token parses out to be
{
"alg": "RS256",
"kid": "0bf399b0b4d76791901ec9f55156d37e",
"typ": "JWT"
}.
{
"nbf": 1527890600,
"exp": 1527894200,
"iss": "http://commandcenter:5000",
"aud": "http://commandcenter:5000/resources",
"client_id": "commandcenter",
"sub": "e7768212-7a0f-408a-8c9f-ff44f95e776e",
"auth_time": 1527890600,
"idp": "local",
"scope": [
"openid",
"profile"
],
"amr": [
"pwd"
]
}.
{SIGNATURE}
I've seen 2 main ways in which tokens are signed. One is just using some passpharase that everyone magically has to know in order to verify the token. We don't want to have to manage updating multiple clients when a passphrase changes, so this is not an option for us. The other way is to use essentially a PKI method much like how HTTPS keys are exchanged and authenticated using X509 certificates. I have a few questions about this and this particular example:
1. Why isn't the 3rd and final section of the token Base64 encoded? I'm guessing its Base64Url, is that right? The rest of the segments use Base64, why not this one as well?
2. We would like to use essentially SSL certificates for signing and I presume this example token has done the same, but how does the receiver know which public certificate it should fetch in order to validate this token? Shouldn't the certificate serial number be provided?
3. Why is this signature so big? This seems like way to many bytes for just a signature, is there other data packed inside?