Keycloak with clients that have different session expiration length - keycloak

I am very new to keycloak and want to use it for SSO, but some of our apps want to have different session expiration length, say App A is 4 hours, App B is 8 hours.
To make this work, I will need to set the keycloak to the shortest expiration time, in this case is 4 hours.
Is this the only way? Or by a long shot, keycloak can treat each client differently?
eg.
Keycloak session set to 16 hours, if request from App A, it will force user to login?
https://keycloak/oicd/login/?client_id=app_a&....

It is not clear what session means in your case. User is logged, when app has valid id/access token, which is usually short lived, e.g. 5 min and app refreshes/renews tokens periodically (for example with refresh tokens). In theory that refresh can be running indefinitely, but actually Offline Session timeouts are applied for refresh token, so it can be limited.
There is also IdP SSO session on top of that, which mean that user/app will get token without asking for user credential, when user is redirected to the IdP login page = user was authenticated recently and it still has that SSO session.
Anyway, Keycloak gives you option to customize session/token timeouts on the realm level:
Some of those timeouts can be overwritten also on the client level:
Note: there can be many dependencies, between all those timeouts, so always test your setup to see how it fits your needs. Example, how it can be complicated: How to specify refresh tokens lifespan in Keycloak

Related

Using JWT(?) to authenticate users for an electron app with persistence

I'm looking to secure my electron desktop app with user credentials (username + password), but I'm having a hard time finding the right technology to use. Requirements:
Number of activations can be determined (e.g. x copies of the app can be activated at any given time)
The user can deactivate/revoke access to all active instances remotely.
The activated copy will not need to be re-authenticated manually indefinitely if the user does not log out remotely.
For example, the user can authenticate themself, not use the desktop app for a long time then they aren't expected to log in again when they re-open it.
I am currently looking at JWT as it somewhat satisifes 2. However i've read that it's advised that the tokens not be saved in a database, so if I need to blacklist tokens, the blacklist would be a forever growing collection which is not ideal (unless you had a cronjob to remove expired tokens)
I'm not sure which solution would be ideal here that would meet the requirements.
Use JWT. Create two tokens: access token and refresh token. The access token will be short-lived (minutes), the refresh token will be long-lived (hours, days, weeks). Follow the best practice in token handling (Access token and Refresh token best practices ? How to implement Access & Refresh Tokens). Also comply with the OWASP ASVS V3 requirements regarding session handling
You actually do want the refresh token to expire. Else you would need to hold them in some blacklist forever. Forever is pretty long. Having to delete the expired logs from storage is a small price to pay for this level of flexibility you are willing to implement.
Make the refresh token hold two additional attributes:
Unique identifier
Human readable name
so the user knows which tokens he is invalidating. You would put into the blacklist the unique identifier and the expiration date.
You can identify how many copies of the application are being used based on the active access token count.

How to handle JWT expiration

I have a question on "make the browser send out a request to exchange for a new token at the sixth day. Accordingly, on the server side, create a restful API named /token/extend which will return a new token if given a valid token."
Let's assume that I implement this concept. When token is about to expire, we will generate new valid token if old valid token is provided.
Now, let's assume, Hacker gets the token. He uses this token to communicate with APIs. Hacker communicates for 6 days. On 6th day, our "/token/extend" API will generate new token for him so he can communicate for another 6 days, and probably forever. Will this situation occur? or Am I missing something here?
The general way you would force your users to obtain a new token after 6 days would be by simply setting the exp field (expiry) in the claims of the JWT to expire after 6 days. The exact mechanism by which users would use to obtain a new token depends on your implementation.
The most basic implementation would be to just let the incoming request on the sixth day to fail, forcing the consumer of the API to redirect to the login page. From there, the user would have to login again to obtain a new valid JWT. A more elaborate method would use refresh tokens. With this approach, when the user first logs in, he would receive an authentication token with a 6 day expiry (as before), but would also receive a refresh token which would expire a little bit later. On the sixth day, when the user tries to access a service, the request would again fail. However, in this case, the consumer (e.g. a website or mobile app) could take the refresh token and request a new access token under the hood. This would be a more seamless way of handling the mandatory 6 day expiry. Note that with the refresh token approach, the user might never know about the 6 day expiry.
Regarding your concerns about hackers obtaining other people's tokens, you should mostly just forget about this. If someone stole your wallet, there is all sort of havoc he could do to you, e.g. using your credit cards, stealing your identity, etc. The same could happen with a stolen/sniffed JWT. The best practice here is to just make sure you are using two-way SSL for all communication, and also encourage your users not to use your services in places like Internet cafes.

How to extend token expiring time if user is not active for a set period using JWT?

Given an example here for a normal web app.
Traditionally, we use session and set timeout = 30 minutes. if session expires we will redirect user to login. (Expired time will be extended when user/browser interact with web app)
Using JWT, how to achieve that?
I know something about "token refresh", when short-time token expires it will refresh a new one using refresh-token.
But it looks like it don't care about whether user is interacting with web app or not. So as long as refresh-token is alive, the browser can always get a new short-life JWT.
So the question is: How to extend token expiring time if user is not active for a set period using JWT?
When the user interacts with your server then your server can decide to issue another JWT with a new expiration time (not at each request but e.g. 5 min before the current JWT expiration time). If the client receives a new JWT, then it replaces the old one.
When the user does nothing, no new JWT is issued and the JWT will become invalid after the timeout.
If the user is active, then issue a new JWT every time the user enter in the web application and every period of time (for example 1 hour)
If the user is not active but the browser is open, it can request a new JWT to server in background. The token must be requested before expiry time and then replace the token in localStorage or cookie. This technique also can be applied to standalone applications
If browser can not request a new token (closed, not active, etc) then the token will expire and you can redirect user to login in the some way that if server session expires
Check this JWT (JSON Web Token) automatic prolongation of expiration

Keycloak: Can I set the expiry of a token per client/user/role?

I'm currently setting up Keycloak to offer protection for some services. There will be both external customers and internal services consuming the same endpoints on my services.
Can I set the token expiry on a user or role or client level, or use a mix of tokens and Basic auth?
It is possible to configure a different lifespan for access tokens on a per client basis. In Keycloak admin console go to a client settings page and expand the "Advanced Settings" section.
This screenshot is taken from Keycloak 4.8.1.Final.
EDIT: Be aware that is override is applied to Authorization Code Flow only. The access token lifespan for Implicit Flow can still (Keycloak 7.0.0) be set on realm level only!
EDIT: Since Keycloak 10.0.0 it is also possible to override session idle and session max timeout per client.
It can be done on realm only, correctly mentioned by #maslick as Keycloak do SSO and expects multiple clients in one realm.
Although, you can code accordingly in your application picking the Keycloak session if you need it to be custom.
Unfortunately, token expiration time can be set on a per-realm basis only.
Can I set the token expiry on a user or role or client level, or use a
mix of tokens and Basic auth?
Currently, Keycloak does not offer (out-of-the-box) user- or role-based token expiration. IMO no one in this thread has yet covered how the SSO-related fields influence the access token lifespan. It is also missing references to ID and refresh tokens. I will try to expand on this.
Refresh Token lifespan
Currently, the refresh token lifespan cannot be explicitly set. Nonetheless, one can implicitly set the refresh token by tuning the values SSO Session Idle, Client Session Idle, SSO Session Max, and Client Session Max. One can read more about it on this SO answer.
ID and Access tokens lifespan
TL;DR One can infer that the ID and access token lifespan will be equal to the smallest value among (Access Token Lifespan, SSO Session Max, and Client Session Max).
In Keycloak (KC), one can explicitly set the access token lifespan (ATL) at the realm and client levels. Those options are not available for the ID token lifespan, but KC will make it the same as the ATL. Therefore, when one changes the ATL, one indirectly sets the ID token.
By default, the ATL is 5 minutes (except for implicit flow which is 15 minutes). One can change those values at: Realm > Realm Settings > Tokens. How it looks on the:
old KC UI:
new KC UI:
Even though the fields are labeled as 'Access Token', KC uses (as previously mentioned) their values to also set the ID Token lifespan as well.
Those values can be overridden on a per-client basis in Ones Realm > Clients > ones Client, then on the:
old KC UI, one goes to the section Advanced Settings
new KC UI, one switches to the tab Advanced and goes to the section Advanced Settings
So far so good, but now things will get a bit more interesting.
Interplay with SSO-related fields
As with the refresh token lifespan, the ATL also depends on other values, namely:
SSO Session Max
and Client Session Max.
Let us consider for now only the realm settings SSO Session Max and Access Token Lifespan, when:
SSO Session Max > Access Token Lifespan, then ATL = Access Token Lifespan
SSO Session Max <= Access Token Lifespan, then ATL = SSO Session Max
So, one can infer that the ATL is bound to the smallest value between the Access Token Lifespan and the SSO Session Max, which makes sense.
SSO Session Max is related to Single Sign-ON; we still need to consider the value of Client Session Max in the realm settings, which when unset, is the same as SSO Session Max.
If Client Session Max is set, in the context of the ATL, it will override the value from SSO Session Max, BUT only if that value is lower than the value from SSO Session Max.
Let us see the following examples: Access Token Lifespan (at realm settings) = 30 minutes, SSO Session Max = 10 hours and:
Client Session Max = 1 hour, then ATL is equal to the Access Token Lifespan
Client Session Max = 60 seconds, then ATL is equal to the Client Session Max
So in short one can infer that the ATL will be equal to the smallest value amongst the fields Access Token Lifespan, SSO Session Max, and Client Session Max.
Finally, the fields Access Token Lifespan and Client Session Max from the realm settings can be overwritten respectively by the Access Token Lifespan and Client Session Max in the clients themselves, which will affect the ATL for that client in particular.
The same logic applies but instead of considering the values Access Token Lifespan and Client Session Max from the realm settings one needs to consider those from the client advance settings.

OAuth REST access_token and instance_url expiry time?

I am working with Oauth2.0. In that i could able get the access_token and instance_url. Is there any expiry time for these two.
Can I store them and use it for all my REST calls without getting the new access_token and the instance_url. Is it possible for me to use it for long hours or even days.
The access token is only valid for the length of a session (as defined in the Salesforce Org's settings — I believe the longest this can be is 8 hours without activity), as it's actually a session ID, that said, you should also be given a refresh token. The refresh token has a much longer lifetime and can be used to authenticate the user once the session has expired, without them having to enter any credentials — this allows you to do it in the background without them even having to concern themselves with the login process.
model metrics do a good job of explaining the token flow here.