If the ASP.NET session timeout is 20 minutes (sliding), what’s the impact of ID token lifetime and the Web app session lifetime?
The ID token lifetime seems absolute (60 min default). What happens when it expires, is a new authentication triggered at the next request or does it happen only when both the ID token and ASP.NET session are expired?
The Web app session lifetime can be both absolute or rolling (1440 min default). Is it rolling with regards to B2C or to the ASP.NET application? What’s the relationship between the ID token lifetime and the Web app session lifetime? My understanding is when the ID token is expired, if the Web app session is not expired, the user does not have to enter his credentials again, I am correct?
I’ll start by explaining some key scenario differences between several of the concepts you’ve mentioned below.
ID tokens: As you’ve mentioned, ID tokens lifetimes are “absolute” – while you can configure the lifetime of newly created ID tokens in the admin portal, once an ID token is created, there is no way to extend the lifetime of an existing token. If you send the ID token to some endpoint on your service, and the service determines the token is expired, then the client must acquire a new ID token from B2C.
B2C Web app session lifetime: Based on how this is configured for your policy, B2C’s web app session lifetime determines whether a new authorization sent to the /authorize endpoint can be handled without the user needing to interact with UI. Note, however, that a redirect still occurs. Commonly, the result here is a redirect by the customer’s web app to B2C’s /authorize endpoint, followed by an immediate redirect back to the customer’s web app with a newly minted ID token (which would have a new/full ID token lifetime). Visually, this can look like a “screen flicker” as the browser is quickly directed away, and back again. When this happens, if the “rolling” type has been picked for web app session lifetime, then this non-interactive web app session can be used for a new (by default, 1440 minute) window, whereas if choosing “absolute”, the time limit will still be based on the last time a fully interactive web session was performed.
As I mentioned, I’m not myself very familiar with how ASP.NET sessions work here, but the “rolling” web app the admin portal is referring to is for B2C, not ASP.NET (we have no special interaction with ASP.NET). My guess is that the ASP.NET layer is an additional layer on top of what I’ve described here. Presumably, the ASP.NET session is controlling how often ID tokens are requested and verified by the service, but you may want to follow up with that with the ASP.NET team specifically.
Another scenario not mentioned below regarding silent reauth is “refresh tokens”. Refresh token redemption is truly silent (ie, no screen flicker), and may be a preferred solution based on your setup. If you are using a single page application (aka “SPA”), there are other options available as well.
You can find out more information here: https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-apps
Related
In the Azure B2C documentation you have this information about silently acquiring new access tokens when the previous one expired.
ID tokens and access tokens both expire after a short period of time.
Your app must be prepared to refresh these tokens periodically. To
refresh either type of token, perform the same hidden iframe request
we used in an earlier example, by using the prompt=none parameter to
control Azure AD steps. To receive a new id_token value, be sure to
use response_type=id_token and scope=openid, and a nonce parameter.
Is there a way to do this without an iFrame?
You can do it with a full redirect by calling acquireTokenReditect() with MSAL. There is no other option in a javascript app. This of course is not going to be a good UX as you’d need to do it every time the api resource changes or scope changes.
I am in the midst of designing a single auth model that works for both SPA+API server and web applications.
Got some insight from the here link to use access/id token in cookie form (none httpOnly) for web application integration.
Attempting the OIDC public client and PKCE way, the integration is workable for SPA+API server but I am stuck at the token
renewal flow for the traditional web application. Oidc silence renewal flow is pretty front channel initiated and when the access token is expired, what will be the options for web application to retrieve the new access token ? (assuming the session from IdP is not expired)
You should use the OpenID Connect hybrid flow. This will issue tokens to your front-end and traditional back-end Web app. It will also allow you to issue different kinds of tokens with different claims to each.
More specifically, the front-end may only get:
An ID token; or
An ID token and access token; or
An ID token and access token and a refresh token.
Also, the back-end may only be issued any combination of these.
You can test the hybrid flow if you're unfamiliar with it using oauth.tools.
For the front-end, you have a couple option to continue access the protected resources without prompting the user:
Rely on SSO (the front-channel approach you mention) or
Issue the SPA a refresh token
In the refresh case, take note of the best common practice for this:
The refresh token should be created anew whenever it's redeemed
Refresh tokens must expire by a certain time or after a certain period of inactivity
Renewed refresh tokens must not be renewed beyond the lifetime of the original
If you do these things, there's still risk involved in issuing an SPA a refresh token, so consider:
Not issuing one or
Doing a combo of the two approaches
When doing a combination (SSO + RT), you could cap the lifetime of the refresh token to something that shouldn't greatly impact the user's interaction with the API while still requiring them to prove control of the original credential with some amount of frequency that offsets the risk. In such a case, the friction of having to login could be lessed by allowing SSO at the authorization server. This too introduces risk, so its lifetime should be limited.
I would look at all these timeouts as knobs that you can turn and twist to ensure an adequate amount of security.
Extending the period of access for the traditional, back-end application can be done using the same two options (SSO or RT).
I am using MSAL for Azure AD authentication in a Xamarin app. The validity of the token is 1 day (seen using the value of ExpiresOn of AuthenticationResult).
My problem is that, after 1 hour, AcquireTokenSilentAsync fails and then AcquireToken needs to be called.
I am not able to understand that even though the token validity is 1 day, and the validity of refresh token is even more, why is it asking for authentication after every 1 hour ?
Can this be changed using any parameter value or any other way ?
Just to make a small clarification, MSAL doesn't actually issue tokens or decide a token expiration, but rather ingests an acquires token from the Azure AD STS.
MSAL will automatically refresh your access token after expiration when calling AcquireTokenSilentAsync. You're likely not getting automatic silent refreshes due to some kind of token cache miss. It's hard to say the specific issue without seeing your code, but i'll recommend comparing it against the official MSAL Xamarin code sample.
If you're building a Xamarin app, then it's a public client. The default token expirations right now are:
Access Tokens: 1 hour
Refresh Tokens: 90 days, 14 day inactive sliding window
Azure AD does allow you to configure these token expirations in PowerShell. You can define a token lifetime policy and then assign it to the specific Service Principal, across the tenant/organization, or on the application object. The other thing to keep in mind is if you're requesting a token for a specific resource, then the policy must be set on that resource rather than the requesting service principal or app. For more info on this, checkout configuring token lifetime in Azure AD.
There was an issue with the TokenCache due to which token was not stored properly and I was getting an exception. This has been resolved in the newer versions of Xamarin Android. Bug defined here
In my case, company B (domain B) hosts a portal, which has link to my web app (domain A). If user clicks on hyperlink on the portal to my domain, he/she should be automatically logged into my app.
Existing poilicies that i cannot change:
User also has the ability to log into my domain directly, without going through the portal by supplying user id/password.
Also, existing company policy for user provisioning is that even if user log through portal of company B, they first need to have a user account with my company. Hence, the user will have account with portal company and my company.
Given these constraints, my plan for is following to provide automatic login from the portal.
When the user logs in to the portal, the portal company will generate a temporary token (UUID) and attach it as a query parameter to the hyperlink to my web app. When user clicks on my web app's hyperlink, my web app will receive a GET/POST request on the server side for a protected resource. At the server side, my web app will over https (probably two way SSL) invoke a URL on the portal's side, passing the temporary token. The portal side responds with a user id. My web app will map the user id with user's credentials and create a session for the user and allow access to the protected resource.
When the user logs out of the portal application, the portal server will make an Https request to my web app at a prespecified URL to log the user out. Since it would be two way SSL, logout url is protected.
My questions are following:
Is there a standards based approach to achieving the above scenario. In near future, my company is planning to support OAuth 2.0 and i want to ensure that the above scenario will not violate any OAuth standard. As per my understanding, OAuth 2.0 leaves the validation of the access-token to the implementations. I am hoping that the temporary token described above is sort of access-token.
Once the user closes the portal browser, is it possible for browser to destroy the cookie. In this case, if user opens another browser later on, he/she should authenticate again.
Is there a standards based approach to achieving the above scenario. In near future, my company is planning to support OAuth 2.0 and i want to ensure that the above scenario will not violate any OAuth standard.
You kind of like answered your question already. That "standard-based approach" is OAuth which a Standards Track already documented by IETF in RFC 6749 and has been adopted by many software entities. If you don't implement OAuth then you are not violating the standardisation rules, you will be violating it if you claim to have implemented OAuth authorization in your system which clearly you haven't.
As per my understanding, OAuth 2.0 leaves the validation of the access-token to the implementations.
Well, OAuth is a bit more complex than just generating an access token, there's an authorization grant request involved before you can request an access token. You could also expose a token refresh endpoint if the life span of the access token needs to be extended by the client. So, there's more than just access token requests involved in OAuth authorization process
I am hoping that the temporary token described above is sort of access-token
What's an access token? It is up to you how you implement an access token, the implementation details belong to you and nobody else. The only thing that you need to guarantee is that the access token represents the authorization issued to client and its scope, in other words, given an access token your system should be able to identify a client and the scope of this client...what the client is allowed to do, what resources the client is allowed to request. Be aware that OAuth defines clients which doesn't directly translate to users, it could well be a user, another system, component or app.
Once the user closes the portal browser, is it possible for browser to destroy the cookie. In this case, if user opens another browser later on, he/she should authenticate again
Absolutely, yes. This is not related to OAuth at all, it's up to the client what they do with the access token and how they store it. If your system issues a non-persistent cookie, then as soon as the user closes the browser then the browser session is destroyed and also the cookie. All modern web development technologies offer cookie management implementations such as JSP, ASP.NET, PHP, etc. So I would suggest to store the access token in a non-persistent cookie and have your authorization server inspect requests to all protected resources by checking for the authentication ticket/cookie (where the access token is) and validate the access token, if the access token (or cookie) is not present then reject the request since it is an anonymous request to a protected resource.
Hope it makes sense
I'm writing multiple client apps (iPhone/android/windows phone) that are going to call into an Azure ACS secured mvc webapi controller (sorry for the acronym soup).
Securing the webapi is straight forward with WIF (well, .net 4.5), and I can passively log in without issue.
I have also created a POC iPhone application that uses a web browser to get the user to authenticate against the azure AD IP, then using the guide here I can get a javascript token.
Now I guess the next step is to use the JSON Web Token Handler on the web controller and I should be able to pull the data fine.
However how long can I store the token for? Should I try the webapi endpoint, and if it's rejected get the user to re-authenticate, or is there anyway to set the token so it either never expires, or it expires after months?
Thanks
Ross
AFAIK, ACS limits the lifetime of a JWT token to 24 hours (This is not a JWT constraint- it is an ACS one); after that you have to renew it. Storing a security token for a long time is in general not a good idea since the user may be deactivated or her claims might have changed.
You can know when a token expires by looking at the "exp" member of the security token. The security token you will receive from ACS is BASE64 encoded. If has 2 to 3 parts separated by a dot. If you decode the token, then the second part of the token will give you the "exp" member. Microsoft has provided toolkits for ios at
https://github.com/WindowsAzure-Toolkits/wa-toolkit-ios. (toolkits for android etc also exist).