How jwt token get reissued in azure ad OuthImplicitFlow - azure-active-directory

Currently the scenario is. When I am trying to access my app,it first sends my app to Microsoft login page and after successful login it returns a id token which is used to retrieve the data from backend server. Now the expiry time of token is approx 1 hr. Now when this token expires, Microsoft issues a new token(JWT Token), it not redirects me back to login page.
But ideally it should be redirected to login page, as in implicit flow, there is no refresh token. Then on what basis it is issuing a new token ?
I am using Microsoft adal library in my front end side for authentication.

here's the link: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow#refreshing-tokens
The implicit grant does not provide refresh tokens. Both id_tokens and
access_tokens will expire after a short period of time, so your app
must be prepared to refresh these tokens periodically. To refresh
either type of token, you can perform the same hidden iframe request
from above using the prompt=none parameter to control the identity
platform's behavior. If you want to receive a new id_token, be sure to
use id_token in the response_type and scope=openid, as well as a nonce
parameter.

Related

Is Refresh Token relevant for OIDC IdentityServer Azure AD SSO Implementation?

I have an implementation of IdentityServer4 which connects with Azure AD for authentication (OIDC). In the callback method, using the IdentityServertools, I am generating the access_token and redirecting the user to SPA with the same. The SPA then stores the access_token into localstorage and uses it for authentication.
Normally, when my SPA app hits the token endpoint of the IdentityServer4, it gives access_token and refresh_token and then uses refresh_token to re-authenticate a returning user.
In this case of SSO with Azure AD, do I need to generate refresh_token manually? If yes, I can build on top of default implementation and that's not the problem (However, the docs suggest against of changing the IRefreshTokenService implementation or building something from scratch)
My real question is, is there a need of refresh_token here? Because refresh_tokens are stored in DB and never get's deleted and after sometime, these refresh_tokens table will swell (right now it already has 80k rows). The user is expected to click on a small tile inside SAP's Successfactor - that will open the signin/consent screen of Azure or will directly take the user to the main page where zhe will just answer a question and done. So it's hardly 2-3 mins business. So I can continue to generate access_tokens from my IdentityServer4 for every click as I don't expect the user to stay authenticated in the browser if zhe has logged out from SAP's Successfactor (or any other app linked with Azure).
Please advise, if I should generate refresh_token? Is it a good architecture?
Access token is used to prove the request is allowed to access the resource(such as api from ms or your custom api) and refresh token is used to refresh access token to make sure the access token isn't expired. Access token will expire in an hour by default and refresh token has 90 days.
At this point, we can easily find the refresh token is designed for some special scenarios because the expired time for refresh token is much longer than access token's expired time, but we can also generate a new access token in other way such as using msal or sign in again.
As you said in the question, you can generate an access token by one click and you don't expect users to stay authenticated for a long time. So I think it's unnecessary for you to use refresh token.

IdentityServer4 refresh token never expires

We are using IdentityServer4 and have an issue on using refresh token.
Here is my client configs:
Grant Types:
client_credentials
hybrid
Access token lifetime:
60
Identity token lifetime:
900
Absolute refresh token lifetime:
240
Sliding refresh token lifetime:
60
Refresh token usage:
OneTimeOnly
Refresh token expiration:
Absolute
I am checking access token life time and when it is about to be expired I use refresh token to get new access token. After 240 second the access token life time does not extension and my client goes to Identity Server and it issues new set of tokens for my client.
I want my user enter username/password after expiration the refresh token buy Identity Server issue new tokens instead of asking credential.
Any Idea?
If I'm understanding correctly you want to force the user to interactively authenticate from your client? If so the max_age=n or prompt=login authorize endpoint parameters can be used to trigger that flow and then you can validate the auth_time claim within your client to ensure it's recent enough.
Currently this is happening without prompting because the user still has a valid IDP session via the authentication cookie. I'd recommend using the above method over and above setting the IDP session to be aligned with your client application session lifetime.

Identity server 4 and Angular app authenticate to achieve forever lasting session

Current structure:
I have angular app as Client, API as data source and Identity server as Identity source. In angular I authenticate user against identity server and use returned token to authorize user against API. Which Grant type should I use to authenticate my angular app user against identity server?
According to http://docs.identityserver.io/en/release/topics/grant_types.html, I should use Implicit grant type.
Problem is that with Implicit grant type there are no refresh tokens. So my question is, how should I keep my user session alive in angular app (access token valid) ? - without asking user to authenticate himself after every time access token gets expired.
My goal is to have session alive (token valid) until its killed by user (logged out)
Yes, the Implicit flow is the one I would use. If your authentication provider supports sessions, you can use OpenID Connect to get new tokens without user interaction. Before the token expiration, create an authentication request (/auth endpoint) in a hidden iframe with prompt=none URL parameter (id_token_hint=... parameter should be present too according to the OpenID Connect RFC). If the user session is open, you will get new tokens, otherwise error is returned (user interaction required).
There is the OpenID Connect Session Management RFC that describes this process and more (single sign on).

Google OAuth2 flow and id_token refresh

I am having troubles in implementing OAuth in the right way.
I use a client/API architecture (Angular for front and Node.js for back) and I would like user to sign in using Google OAuth authentication only.
Here is what I think is the right way for the moment (tell me if I misunderstood something) :
Angular open a Google popup asking user's consent.
Once the user agree, Google Authorization server sends back to angular a verification code.
This verification code is forwarded to an API endpoint.
Then, the API asks Google Authorization server to exchange this code for an access_token, an id_token and a refresh_token.
Google sends those 3 tokens.
The API uses access_token to retrieve user from Google API
The API persists the user
Here is the little dillema, in my opinion, the access_token and refresh_token should be stored into the database and the id_token should be sent back to Angular client.
This way, it would allow the API to ask for resource in Google API and if the token expires it can still ask for a new token thanks to the refresh_token.
Client-side, the id_token is embedded in all requests thus allowing the API to identify the client and verify his authentication with Google certs from https://www.googleapis.com/oauth2/v3/certs.
Supposing this is right way to use tokens, how could I deal with id_token expiration since client does not have any refresh token ?
Thanks !
I do it slightly different (I have the same basic architecture though).
Angular decides the user needs to log in and displays a login popup.
The url in the login popup is not serviced by angular, but is instead directly run off of the backend server: /auth/google . (I use hapijs and bell, personally).
/auth/google is serviced by a bell plugin and initiates the OAUTH dance.
the end of the OAUTH dance results in my node server generating a local token (I just generate random bytes and store them in redis mapped to user ids)
because the initial login popup was created by window.open, the success page (generated on the api side rather than in angular) can use window.opener.postMessage to communicate the token back to the angular runtime.
This way, all my sensitive google credentials (the user's oauth token, refresh token if needed, and my application's api ID and secret) are only on the server, except for during the OAUTH dance relay when they're in a URL string during the client redirects. This is reasonably secure.
Then for all the actual user interactions with the api, I use the token I generated in step four to authenticate. This could be a JWT if you wanted, but I don't do it that way; I just use redis to map from 'longrandostring' -> userId. That lets me (for example) force everyone to re-login if I wipe the redis database that has all the tokens stored, or I can write a lua script to delete all the entries that map to a certain userid.
If you need a refresh token, you can set access_type=offline in the initial request to oauth2/auth, and you'll get a refresh token as part of the response, unless you've previously gotten a refresh token. You can then persist it on the server side and get new access tokens as needed. If you set approval_prompt=force as well, you'll force a new consent screen and be guaranteed a refresh token (but after some small number of refresh tokens granted to a user, older ones expire on the same application so it's best to only request them if really needed).

OAuth 2.0 with GMAIL API using

I am trying to create a sample program for Install Application to access google mail api using oAuthentication. But I have a query before start working on it.
I read on most of doc and following this link https://developers.google.com/identity/protocols/OAuth2InstalledApp
First we need to request for token by providing ClientID and SecretKey
That will return Token in response that Token is pass to other google service which we want to access.
During this process code open the browser (Single time) to get token id. It can not happen without browser.
Can't we do http request to google then get respond from it without using browser, like access any rest api we do?
From Google's Using OAuth 2.0 to Access Google APIs:
The authorization sequence begins when your application redirects a
browser to a Google URL; the URL includes query parameters that
indicate the type of access being requested. Google handles the user
authentication, session selection, and user consent. The result is an
authorization code, which the application can exchange for an access
token and a refresh token.
The application should store the refresh token for future use and use
the access token to access a Google API. Once the access token
expires, the application uses the refresh token to obtain a new one.
You have no choice but to redirect the user to Google the first time the user is using your application. However, you can ask for a refresh token that you can use to refresh the access token after this first login, which usually expires after one hour.

Resources