I am trying to implement refresh tokens with OIDC and OAuth2 and am having trouble understanding the workflow. From what I do understand, using the Authorization Code flow, what gets the refresh token in the response from the /token endpoint is the presence of the offline_access scope in the /authorize request.
My question is how does the request to the token endpoint know that it should return a refresh token for that user logging in, if the offline_access scope is only sent to the /authorize endpoint or should that scope also be present in the token request? Or is this a case where the refresh token should be generated and stored during the /authorize workflow, before the code is returned and then just looked up in the /token workflow to be returned there?
Specifically following this workflow:
Scopes are sent during the Authorize request and from the Authorization Server's viewpoint the following actions are performed:
code is returned to the caller
code is cached with a short time to live (eg 1 minute)
scopes are cached
in some flows other details such as a PKCE verifier are also cached
Next the client makes an Authorization Code Grant request to exchange the code for tokens and the Authorization Server performs these actions:
Looks up the code
Applies PKCE verification checks
Checks the redirect URI matches that of the original request
Looks up cached scopes
Looks up details from the OAuth client configuration, such as the refresh token lifetime
Generates tokens based on the above data
Deletes the cache entry, so that the same code cannot be processed again
Returns tokens to the caller
It is useful as an application developer to have an understanding of the key points of the AS behaviour, as above, though I expect I'm missing an important point or two. My main focus tends to be integrating flows in my UIs and APIs.
Of course when it comes to the Authorization Server, we should always use a certified 3rd party implementation, such as a low cost cloud or free open source solution.
Related
We wish to use our own httponly strict cookie with access and refresh token in it for our microservices architectures.
We are primary using OKTA Authentication API to log users with our own custom Sign-in page.
We were able to get the access_token on the authorize endpoint using the responsetype=token with sessionToken and redirecting the result as a form_post on our back-end endpoint.
I was unable to retrieve the refresh_token despite adding the offline_access in the scope even if it is checked in my okta application setting.
I don’t want to use resource password flow since we prefer using sessionToken which will work with multi factor if needed in the future.
I also try using the code flow and redirecting the result on our back-end but since the code flow is client-side it’s return this error "PKCE code verifier is required when the token endpoint authentication method is ‘NONE’." This error occur even if we choose a .NET application
How can we retrieve the refresh_token server-side with Okta?
Responded to your post here https://devforum.okta.com/t/getting-refresh-token-server-side-sessiontoken/12419/3.
Aside from making a call directly to /token with your access token you can also check our Early Access feature called Refresh Token Rotation. Let us know if this helps!
I was able to use the CODE flow and redirect from server-side to the authorized endpoint like so:
https://{YOUROKTADOMAIN}/oauth2/default/v1/authorize?client_id={YOURCLIENTID}&response_type=code&scope=openid%20offline_access&response_mode=query&redirect_uri={YOURSERVERSIDEGETURI}&state={Guid.NewGuid()}&sessionToken={SessionToken From Auth API}
This call will post back to my same server, so i can handle token myself and create my own cookie.
In the last few days I've been reading on Authentication with refresh and access tokens, but this is one thing I can't find the answer to. Let's say an expired access token is sent. Should the backend automatically refresh it (if a refresh token was provided), or the refreshing should only be done at a refresh endpoint?
As an example, consider the two following auth flows:
Automatically Refreshing
User authenticates with username and password. The API sends back a short lived access token containing his data, and a long lived refresh token.
For every request that requires authentication/authorization, the user will send both tokens on the request headers.
If the access token is expired, the API will check if a valid refresh token was sent, if it is active and if it belongs to the same user as the access token. If everything looks good then it will sign a new access token and update the response headers with it.
Front-end doesn't have to worry about refreshing the token, but it still has to look up response headers after each request to check if a new token was sent.
Manually Refreshing
User authenticates with username and password. The API sends back a short lived access token containing his data, and a long lived refresh token.
For every request that requires authentication/authorization, the user will send his access token.
When the access token expires, the user will send his refresh token to the refresh/ route. The API checks if the token is valid. If everything looks good, it returns a new access token.
After every request, the client has to check if the token expired, and if it did it will have to perform a new request to refresh the token. More requests are being made to the server, but on the other hand responsibilities are better separated, since auth route is only responsible for handling access tokens, while the refresh token handling lives in another route.
I've had some hard time finding resources on the subject, so I'm not quite about sure which solution is better, or even if the solutions I described are correct at all. If I had to pick one, I would go with Automatically Refreshing, since less requests are made, and the client side usability looks better, but as I said, I'm not 100% on this, and thus I'm making that thread.
How should access tokens be refreshed?
It feels to me that you are missing a role here, which is that of the Authorization Server (AS):
UI redirects to AS to authenticate the user via password
AS issues an access token and refresh token, then returns them to the UI
UI calls the API for a while with the access token
Eventually the access token expires and the API returns a 401 response
The UI then calls the AS with the refresh the token to get a new access token
The UI then retries the API call with the new access token
Eventually the refresh token expires and the refresh attempt will fail
The UI then redirects the user to sign in again and the cycle repeats
It is always the client's responsibility to refresh tokens and only the access token should be sent to the API. The API's only OAuth job is verify the access token and authorize based on its contents.
It is possible that you have an API that is doing the job of the Authorization Server. I would aim to separate these roles. If it helps my Messages Blog Post has a lot of detail on the messages in a full UI and API solution.
The implementations of the OAuth2-protocol I know use the flow you are describing under "Manual Refreshing". The client has to care himself about the refreshing.
The client can either check the access_token if it is still valid before every request or do a refresh after a failed request due to an invalid token response.
The access_token is short lived and so the risk sending it with every request and having it eavesdropped and misused is limited. The refresh_token is long lived. If you send the refresh_token with every request an attacker has a much greater chance to get hold of it.
If you send both token with every request you would not need the distinction between these two types. You would work with one long lived token only.
Following is the Main Disadvantage of using Automatic Refresh Token Rotation Scheme :-
Let's say the Client makes 2 API calls (API A and API B) at the same time. At the time of triggering these two API calls, the access token was expired. Both of these API calls are carrying the same expired access token and the refresh token (let's assume this refresh token is valid).
Let's assume API A gets handled by the server first. According to the Automatically Refreshing Scheme, the server will check the API A's access token, if that token is expired, server will check the refresh token and if that refresh token is verified (this refresh token is present in the database too), the server will create a new access token and a new refresh token (the refresh token that came with the API will be deleted from the database and will be updated with this new refresh token). These new tokens will be returned to the Client.
API B will follow the same flow. BUT its Refresh Token will be invalid because during the handling of API A, the refresh token was replaced in the database by a new token. API B's Refresh Token is not present in the Database and thus this request will fail.
If you have multiple APIs being called at the same time, Automatic Refresh Token Rotation Scheme will fail as the First API request will replace the Refresh Token when renewing the tokens and the remaining API requests will be coming with a Refresh Token which is not present in the Database !
My experience has been that the OAuth2 access_token requests dont like extra data meaning that you wont be able to send both the access_token and the refresh_token. That would lead to the Manual Refreshing scenario youve described as the only option
I am trying to add the authorization in SAML as part of IDP implementation using SAML 2.0 Bearer Assertion Profiles for OAuth 2.0
Here, the SAML assertion is exchanged for Oauth2 access token. As per specs, the only access token should be returned in exchange of the SAML assertion and refresh token should not be returned. Following is mentioned in the spec regarding renewal of the access token (RFC7521)
An assertion used in this context is generally a short-lived
representation of the authorization grant, and authorization servers
SHOULD NOT issue access tokens with a lifetime that exceeds the validity period of the assertion by a significant period. In practice, that will usually mean that refresh tokens are not issued in response to assertion grant requests, and access tokens will be issued with a reasonably short lifetime. Clients can refresh an expired access token by requesting a new one using the same assertion, if it is still valid, or with a new assertion.
Now, if the access token is expired client can get new access token in exchange of assertion if the Assertion is still valid but how to get assertion if it is expired? If we re-initiate the SSO flow then assertion will be provided to the ACS (Assertion Consumer Service) URL which will cause a shifting from the current screen for an active user. This might cause an issue if the user has any unsaved activity on the page.
How can I provide an Assertion as a response to a request? Is there any provision in SAML for extending assertion directly via a single call to IDP?
You can't "extend" an existing assertion, you'd have to ask IdP for a new one.
The workflow where a new token is requested via an existing assertion is rare but technically possible if you can hold on to the assertion after it's issued. Doing so would require an intermediate step/component between the IdP that issues the assertion and the oAuth client, something that is certainly possible in a number of solution architectures.
The refresh of an expired token via a new assertion would be a much more common implementation choice.
I'm working on an application that uses a token-based authentication system, where the user provides their username / password and receives a token in return (the token gets saved to the database as well). Then subsequent requests will include this token as a custom header and we can use this to identify the user. This all works fine.
Right now if the user doesn't login for 3 days, we expire the token. I was reading a little about refresh tokens in OAuth and I was wondering if I could somehow implement something similar. i.e. when providing the auth token, I also provide a refresh token which can be used later to request a new auth token. In terms of security though, it seems quite similar to just never expiring the user's auth token in the first place. Should I be sending additional information with the refresh token to validate the user?
In OAuth2, the resource server and authorization server are often not the same.
The refresh token is sent back to the client when the access token is issued and when the token is refreshed. The client needs to authenticate itself (using client id and client secret) to use the refresh token. The resource server never sees the refresh token.
Also, access tokens are not stored at the server side as they have a limited lifetime. Refresh tokens are stored and can therefore be revoked.
I have a web app that uses the Google API. The process to authenticate makes two calls to google, the first to get a code and the second to exchange the code for a token. Both calls take a redirect_uri parameter. The first call uses this parameter as I expect, redirecting back to the redirect_uri, however, the second call, to get the token, does not redirect, bar validating it it seems to ignore this parameter, so what is the point of it?
The redirect_uri parameter in access token request is described as REQUIRED in the OAuth 2.0 specification.
The reason behind it is described in detail in the section 10.6 of the same document. In short:
An attacker can obtain the authorization code by manipulating the request_uri of authorization request. The only two parties who can notice this trick are victim (legitimate user) and server. Client remains unaware of these manipulations.
Even with the code an attacker cannot exchange it to access token, yet it can try to deceive the client by sending the "callback response" with the stolen code on behalf of itself.
If client could exchange the code it received to the token, it would grant access to the victim's data to attacker. Fortunately, because client's redirect_uri doesn't match with the one the server has seen, the request will be rejected.