Keycloak Session and Token Timeout: Client login timeout - keycloak

We are currently verifying our Keycloak Session and Token timeout settings to rule out error potential. I think default configuration should do it for our use case.
I think the only worrying value is "Client login timeout" which we've set to 1 minute (like in the screenshot of the documentation).
Documentation here states: Client login is the maximum time that a client has to finish the Authorization Code Flow in OIDC.
I read it but I don't understand it... I guess the documentation copy pasted this from redhat documentation here (or vice versa) but also there is no detailed explanation there.
So my question really is: What is "client login timeout" and what would be a good default for it? A perfect answer for me would just describe the workflow from a user perspective when it fails (like user drank a coffee for 1 minute before clicking the e-mail verification link etc.) and/or a link to further reading

In simple terms it is the time spent by the client to get an Access Token.
It is the maximum time the client has to finish the Authorization Code Flow. The steps involved in the Authorization Code Flow can be found in OIDC specs.
https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps
Client prepares an Authentication Request containing the desired request parameters.
Client sends the request to the Authorization Server.
Authorization Server Authenticates the End-User.
Authorization Server obtains End-User Consent/Authorization.
Authorization Server sends the End-User back to the Client with an Authorization Code.
Client requests a response using the Authorization Code at the Token Endpoint.
Client receives a response that contains an ID Token and Access Token in the response body.
Client validates the ID token and retrieves the End-User's Subject Identifier.

Related

Mobile app authentication using Token based on OAuth2.0

I'm building a REST API using Elixir's Phoenix framework. In the API, I need to authenticate the user by phone number i.e., via sending an SMS OTP code. After authenticating the user, the Auth server sends the Access token and Refresh token to the client. The client(mobile app) stores those tokens locally and sends the Access token in the HTTP header as Authorization: Bearer <Access_Token> in every request to resource server. My actual question is, how do resource server validates the Access token that is received from the mobile app/client?
Does resource server needs to contact Auth server to validate the Access Token? That would a lot of overhead. Please help me understand RestFull API Authentication.
Thanks for taking the time to read my question.
It sounds like you have everything working up to validating the token. You are going to need the public key for the server that signed the token. It depends on what auth server you're working with on how you get that. In some cases you may be able to preload this key as a configuration setting on your backend. Otherwise you can probably get it via https request to the auth server. Most auth servers these days I expect to provide a JWKS api that you can use to get the keys you need. Then with the token and the public key you can use your elixir jwt library to validate that the token you have was signed by the server you trust, meaning the SMS code was validated, and you can proceed with whatever is needed in the backend to handle the request.
If you're using Joken for elixir you can review https://hexdocs.pm/joken_jwks/introduction.html and https://hexdocs.pm/joken/introduction.html for more information.
how do resource server validates the Access token that is received from the mobile app/client?
The same way a nightclub bouncer verifies your driving license as proof-of-age to let you in: by validating the authority and signatures, but it does not need to phone-up your DMV to verify that your license is real because it trusts the signatures (in this case, cryptographic signatures).
That said, some systems do use "reference tokens" which are short (say 32 bytes) of meaningless random data which are used as an unpredictable record identifier for some user-permissions record held by the authorization server. The resource-server will need to contact the auth server initially, but then it can simply cache the auth result itself for some time window.

Why google-oauth API requires redirect-url?

I'm trying to set up an authorization flow with google-oauth2 API.
The task is to authorize users with google accounts in my web-application which consists of frontend and backend parts.
The flow according to the documentation consists of 2 steps:
1) obtaining an auth code
2) exchanging an auth code for a token
In my flow, FE client obtains an auth code from google and submits it to BE, which then exchanges it for a token, so no redirect URL (or sometimes called callback URL) is used.
I do not understand why google API requires me to provide redirect_uri for the second step? Since this step is performed by a server, not a browser, I don't see any sense in this piece of info. The server just calls the POST /oauth2/v4/token google endpoint and receives token in response.
see step 4 at https://developers.google.com/identity/protocols/OpenIDConnect
According to this, it's to guard against stealing the access_token. If a service doesn't check the initial redirect_uri, the authorization code is sent to the hacker's redirect_uri, which can then exchange it for an access_token, i.e. illegal access to the user's account. To actually get the access_token, the redirect_uri is specified again and this time must be checked by the server against the ones that are registered for that application. At that point, the hacker is foiled as the fake redirect_uri doesn't match any of the legal ones. Apparently some servers don't check the redirect_uri during the authorization stage and sending the redirect_uri again when requesting the access_token is meant to provide a final safey check.

Mobile app + REST API authentication

I want to build a REST API which will be used by both mobile app and also a website. I was wondering how would I go about implementing a simple login system for users?
For a simple website, after checking the username and password, one could set a SESSION variable and have the user "logged in".
Now, REST is stateless so I suspect that the above is not the way to go about. I thought that a possible solution would be to have the server generate and return an access token each time the user logs in, and the client will need to attach this access token to every subsequent request to access protected endpoints.
Is the above a viable solution or what is the industry standard for something like this?
(I found OAuth 2.0 to be overkill, but I could be wrong)
There are several token authentication schemes, but if you're looking for the industry standard, then JWT (JSON Web Token) is the way to go. Here's how the process usually goes:
Client sends his credentials (e.g. username and password) to the server.
The server verifies that the credentials are correct, generates a JWT and returns it to the client. Client saves the token in e.g. localStorage.
For each subsequent request, the client will attach the JWT as a part of the request (usually in the "Authorization" header).
Server will be able to decode the JWT and decide if the client should have access to the requested resource.
Now, some interesting features of JWT come from the fact that there is data encoded in it. Some of it everyone can decode, and some only the server can decode.
So, for example, you could encode the user's id and profile picture in the JWT so that the client can use the data from it, not having to do another request to the server to get his profile.
JWT has embedded info about expiration. The server can set the expiration time.
Another cool thing about JWTs is that they are invalid if changed. Imagine you stole someone's token, but it's expired. You try to change the expire information inside the token to some time in the future, and send it to the server. Server will deem that token invalid, because the contents doesn't match the signature attached, and a valid signature can only be generated by the server.

How to design a stateless REST Login with 2 Factor Authentication (2FA)?

I'm struggling with the concept of how to design a stateless RESTful authentication API with multi-factor authentication.
Almost by definition, the need of a 2FA requires multiple states; logging in with a username/password, then submitting a "code" (either a TOTP, SMS-code, answer to a verification question, etc). This further implies a finite-state-machine (FSM) of some sort.
As far as I can tell, the only options which exist in order to maintain a stateless mechanism are:
the client must transmit some state information (ex: current FSM state) when submitting data to transition to the next state,
the state must be persisted on the server side,
the client must transmit ALL data at every request which allowed it to reach the current state
Obviously transmitting ALL data is nonsensical. So this would imply either transmitting state information (opaque or otherwise) in the request or maintaining state on the server.
Or is there some other technique that I am missing?
I'm adding the solution I came up with in case it is beneficial for someone else in the future. Please note that in this case, PVQ stands for "Personal Validation Question" (ie: Knowledge-Based-Authentication).
At the end, I designed my login endpoint to require:
Authorization header (which is a 2FA token) : Authorization: authType=”PVQ”
token=”<tokenid>”
username
password
If the Authorization header is missing, the endpoint returns a 401 and sets a WWW-Authenticate header, indicating that a 2FA token (ie: Authorization header) is required to login. param could be PVQ, SMS, TOTP, etc (based on the user's configuration)
WWW-Authenticate : authType="PVQ"
If the client receives a 401/WWW-Authenticate response, it is its responsibility to call the 2FA endpoints:
challenge/get (receive a challenge token)
Client: sends username/password
Server: Responds with an ID, and either
a question (PVQ),
or just sends sends an SMS code via 3rd party SMS provider
challenge/verify (receive the 2FA Token needed for the Authorization header)
Client: sends
ID received in the challenge/get
username/password
response to the challenge (ie: text answer to a PVQ, or SMS code, or TOTP code)
Server: returns
2FA token value
The client can now call the login endpoint with the required: username/password/Authentication token.
In the end, there is not "state" per say that the client returns to the server, but the tradeoff for this, is that the username/password combination must be sent to every request for the 2FA subsystem.
On the server side, there is some state information stored in the DB in the context of the SMS code or PVQ question that was sent to the user, as well as an ephemeral Authentication 2FA token (single use, and fixed TTL).

Facebook OAuth 2.0 "code" and "token"

Why do you need both a "code" and a "token" in the Facebook OAuth2 authentication flow as described here: https://developers.facebook.com/docs/authentication/ ?
If you look at the OAuth dialog reference (https://developers.facebook.com/docs/reference/dialogs/oauth/), it seems like you only ever use the token to fetch information about the user, and if you specify the response_type parameter as token or code,token, then you get the token on the first time.
Why do you need to get a "code" and then use the code to get a "token" as opposed to getting the token directly?
I guess I'm misunderstanding something basic about how OAuth works, but it seems you avoid the request to https://graph.facebook.com/oauth/access_token entirely if you get the token the first time with the dialog.
Let us take a simple example to differentiate authentication code vs access token.
You as a user want to try a new Facebook app called Highjack.
So you click on the application and the Highjack app asks you to log into your Facebook account. When you are done, Facebook generates an authentication code for you.
This code is then passed to the Highjack server which uses its own FB client id, FB secret and your authentication code to get an access token.
In the above example the authentication code is confirming you as a user is a valid FB user. But the second steps says "you as a FB user is giving access to the Highjack app for certain resources".
If the Highjack app wanted implicit grant (i.e direct access token), then the access token would be visible to you also since it is being exchanged with the browser. This means you can now call all Facebook APIs on behalf of Highjack using the access token. (You can only use the access token to get your personal information but Facebook has no way of knowing who is calling their APIs.)
Since we have 2 parties (You and Highjack) authenticating with Facebook we have this 2 fold mechanism.
Borrowed shamelessly from Salesforce Documentation:
Authorization Code
An authorization code is a short-lived token representing the user's access grant, created by the authorization server and passed to the client application via the browser. The client application sends the authorization code to the authorization server to obtain an access token and, optionally, a refresh token.
Access Token
The access token is used by the client to make authenticated requests on behalf of the end user. It has a longer lifetime than the authorization code, typically on the order of minutes or hours. When the access token expires, attempts to use it will fail, and a new access token must be obtained via a refresh token.
From the OAuth 2.0 Spec:
The authorization code provides a few important security benefits
such as the ability to authenticate the client, and the transmission
of the access token directly to the client without passing it through
the resource owner's user-agent, potentially exposing it to others,
including the resource owner.
So, basically - the main reason is to limit the # of actors getting the access token.
"token" response is intended primarily for clients that live in the browser (e.g.: JavaScript client).
Answer) You need/want both the code and token for extra security.
According to Nate Barbettini we want the extra step of exchanging the authentication code for the access token, because the authentication code can be used in the front channel (less secure), and the access token can be used in the back channel (more secure).
Thus, the security benefit is that the access token isn't exposed to the browser, and thus cannot be intercepted/grabbed from a browser. We trust the web server more, which communicates via back channels. The access token, which is secret, can then remain on the web server, and not be exposed to the browser (i.e. front channels).
For more information, watch this fantastic video:
OAuth 2.0 and OpenID Connect (in plain English)
https://youtu.be/996OiexHze0?t=26m30s (Start 26 mins)
If you look at the flow of Authorization Code OAuth type, yes, there are actuary two steps:
<user_session_id, client_id> => authorization_code
<client_id, redirect_uri, authorization_code, client_secret> => access_token, refresh_token
In step1: the user tells the OAuth Server that "I want to auth this client (client_id) to access my resource. Here is my authentication (user_session_id or what else)"
In step2: the client (client_id) tells the OAuth server that "I've got the user the authorization (authorization_code), please give me an access token for later access. And this is my authentication (client_id & client_secret)"
You see, if we omit step 2, then there is no guarantee for client authentication. Any client can invoke step1 with a different client_id and get an access token for that client_id instead of its own. That's why we need step2.
If you really want to combine step1 and step2, you can do something like this:
<client_id, redirect_uri, client_secret> => access_token, refresh_token
We use this approach in our Open API Platform, and we haven't find any security problem yet.
BTW, there is actually an Implicit Grant type, that is:
<client_id, redirect_uri> => access_token, refresh_token
It is generally applicable to client only application which have no server backend. In that case, the OAuth server must ensure that the redirect URI belongs to that client (same with the register redirect_uri, for example).
The mix-up came because the user on behalf of himself and not the client app authenticate against the authorization server (i.e. facebook).
Its much simple to secure the client app (with https) then the user-agent (browser).
Here is the original formulation from IETF-oauth (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-threatmodel-08#section-3.4):
3.4. Authorization Code
An authorization code represents the intermediate result of a
successful end-user authorization process and is used by the client
to obtain access and refresh token. Authorization codes are sent to
the client's redirection URI instead of tokens for two purposes.
Browser-based flows expose protocol parameters to potential
attackers via URI query parameters (HTTP referrer), the browser
cache, or log file entries and could be replayed. In order to
reduce this threat, short-lived authorization codes are passed
instead of tokens and exchanged for tokens over a more secure
direct connection between client and authorization server.
It is much simpler to authenticate clients during the direct
request between client and authorization server than in the
context of the indirect authorization request. The latter would
require digital signatures.
Theoretically,
Access Tokens cannot tell us if the user has authenticated but auth code does.
Auth code should not be used to gain access to an API but access token should be.
If you have a single page application or mobile application with no or minimum backend, your application may want to access user's FB data directly at frontend. Hence the access token is provided.
In another case, you may want a user to register/login to your app using some external auth service provider like Facebook, Google etc. In this case, your frontend will send the auth code to the backend that can be used to get access token from Facebook at serverside. Now your server becomes enabled to access user's FB data from the server.
Basically, as an extension of Lix's answer, the access code route allows a Resource Owner (i.e. the Facebook User) to revoke authorization for their User Agent (i.e. their browser), e.g. by logging off, without revoking authorization for an offline Client (i.e. Your Application).
If this is not important, then there is no need to use the access code route.
Furthermore, the access code is provided to ensure that the Token provided to a server is actually registered to the Resource Owner (i.e. the Facebook User), and not the User Agent (or a Man-in-the-Middle).
This seems similar to the question of either choosing the implicit vs authorization code grant flow. In fact, here is what looks like an opposite view point?!.
Also, as Drew mentioned,
When the access token expires, attempts to use it will fail, and a new access token must be obtained via a refresh token.
another piece is the refresh token, but I don't see that being explained too well in the FB Docs. If I'm correct, the implicit grant (the direct token) should be really short lived, but that is to-be-enforced and FB.js seems to hide a lot of that (this one I have not looked as deep into).
If I'm correct, the code%20token is an optimization allowing both the User Agent to have a token and allowing for the server to initiate the token exchange process in a single request (as anything over Network IO is considered expensive, especially to a User Agent).
In OAuth 2.0 with facebook, the overall concept is simple as follows.
Step 1. Obtain "Authorization Code" by a GET request
request URI: https://www.facebook.com/dialog/oauth
Params:
response_type=code
client_id={add your "App id" got by registering app}
redirect_uri={add redirect uri defined at the registration of app}
scope={add the scope needed in your app}
Headers: None
Step 2. Obtain the "Access Token" by sending the authorization code as a POST request
URI: https://graph.facebook.com/oauth/access_token
Params:
grant_type=authorization_code
client_id=<add your "App id" got by registering app>
redirect_uri=<add redirect uri defined at the registration of app>
code=<obtained authorization code from previous step>
Headers:
Authorization:Basic encode <App Id:App Secret> with base64
Content-Type:application/json
Step 3. Use the access token got from above step and retrieve user resources
It’s because the access token is given to an AUTHENTICATED client (third-party app) using a shared secret that only FB and the client knows. The only way that the user could directly request the access token is by knowing the shared secret, which would make the secret public and could lead to a man-in-the-middle attack. Further, while FB can guarantee a secure connection to the user, FB can’t guarantee the handoff of the token to the client is secure. However, FB (and OAuth2) does require a secure connection between the client and FB. The access token is tied to the client public ID (usually hashed), which means only the original client application can use it to request the token because the secret is sent along with the authorization code to get the access token.
You recieve a token when the user logs in. But you might want to change the token when you are performing other actions. EG posting as your app/page or posting as a user with offline_access.