MSAL token expires after 1 hour - azure

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

Related

Azure B2C implicit flow: acquire new access token witout the use of an iFrame

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.

Does the retrieved OAuth2.0 authorization code for Azure AD web applications expire?

In order to access resources in Azure AD web applications we retrieve an authorization code using the following workflow:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code
Now my questions is, does this retrieved code also have a specific lifetime (like tokens have) or will it never expire? I guess it won't expire but I need to be sure about that.
Yes, the authorization code has a lifetime of 10 minutes I think.
You use it to get the tokens you need and then throw it away.
You'll get refresh tokens so you can use them to get more tokens later.
ADAL.NET for example handles the token refresh for you, assuming you properly implement a token cache.
Reference: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-id-and-access-tokens (scroll all the way down) (it's for the v2.0 endpoint, but codes are similarly short-lived in v1)
Authorization codes (work or school accounts)
10 minutes
Authorization codes are purposely short-lived, and should be immediately redeemed for access tokens and refresh tokens when the tokens are received.

How to generate access token without any expiration

I need to get access token with expiration date as infinite.
I am using AcquireToken method which generates token with expiration time as 1hour based on UTC.
I need to use this access token for Add-AzureRmAccount command (Need example command for this too for successful login)
How to generate access token without any expiration in c#.
Please help me to work on this scenario.
Thanks in advance.
As Gaurav mantri mentioned that access token without any expiry is a major security risk. And it is not allowed in the Auzre. From Configurable token lifetimes in Azure Active Directory (Public Preview) document, we could know that the default expiration of access
token is 1 hour, and the max is 1 day.
How to generate access token without any expiration in c#.
Simple answer is that you can't and you shouldn't. Access tokens are returned by Azure AD and their expiration is set there only i.e. it is not in your control.
Also, getting an access token without any expiry is a major security risk (that's why "you shouldn't" remark above).
If you're using any Azure AD SDK (ADAL for example), it takes care of automatically renewing your access token so you don't have to worry about renewing that.

Will AcquireTokenSilentAsync not work after 90 days?

I'm building an ASP.NET Web API service which connects to Azure Graph API to get a list of users.
So my scenario is to create an MVC page on this service => let Azure AD admin login and grant permission => cache access_token and use this to call API.
However, I acknowledged that access_token will be expired after 1 hour. Even if it's renewed by using refresh_token, admin will actually have to manually sign in on this service again after 90 days.
I read on some example which use AcquireTokenSilentAsync method from ADAL library. But not sure if it would be useless after 90 days ?
Yes, currently the Access Token will expire within the hour. The Refresh Token will be valid for 14 days, and can be used to obtain a new Access Token and a new Refresh Token. You can carry on doing this for up to 90 days. (Note that these are the current values, they may change in the future.) AcquireTokenSilent and AcquireTokenSilentAsync will attempt to use existing state (i.e. Refresh Tokens, if available) to obtain a new Access Token, or throw an exception if this is not possible.
That said, I suspect that is probably not the best approach for your scenario. It sounds like you are in one of two situations:
You are building a middleware service (an API) that will be used by a different app which is accessed by authenticated users. If this is the case, you can use on-behalf-of flow, where (a) your middleware service is registered as a web app/API in Azure AD, (b) the user-facing client app and obtains an Access Token (for the current user) to the middleware API, and (c) the middleware API uses that Access Token to obtain a new Access Token to the Azure AD Graph API, on behalf of the original user.
Sample: active-directory-dotnet-webapi-onbehalfof
You just need to enable unattended access to the Graph API. If the middleware service is a highly-trusted environment, you can use app-only authentication (also known as "headless", or "daemon" apps) to obtain an Access Token without any user context. (This is the Client Credentials Grant OAuth 2.0 flow.)
Sample: active-directory-dotnet-daemon-certificate-credential
Sample: active-directory-dotnet-daemon
Yes, by default refresh tokens expire in 14 days (access tokens in an hour) but with some configuration I believe it can go until 90 days. This is for security reasons and a good practice. Nothing wrong with it. However, this will only work if you implement your own cache because by default ADAL cache uses memory and upon restart it will lose those tokens.
https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect

MVC WebAPI active authentication

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).

Resources