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
Related
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.
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
I'm trying to access my Table in Azure App Service when user has an authentication. I use server side auth with Facebook. Once the user authenticated, the token was saved into my Setting class, as this post do. Whenever the user come back to App, I want user use their cached token to connect to the table in Azure App Service. How is the best approach to achieve this?
1) Implement client-side authentication with the Facebook SDK. The token provides by Facebook is long-lived (something like 60 days), so you can store it in a private store. I cover private stores in chapter 2 of the ZUMO Book at http://aka.ms/zumobook
2) When you open the app, use the stored token to get a ZUMO token. This is short lived - 1 hour. You can store this too, but it's a waste of time since you can use the unexpired Facebook token to get a new one.
3) Implement an Authentication Refresh process via a delegating handler - I describe that in the ZUMO book too.
You still need to configure Azure App Service Authentication to understand and validate your facebook token (also covered in the book!)
I am looking to using OAuth to secure some web services. OAuth 2 fits nicely for the use cases I have where the user might access his/her own data using API's or grant access to someone to call API's on his behalf.
However, the initial set of API users are not very technical and they would not want to go through the effort of making API calls just to generate tokens. I am thinking of implementing the following solution but am not sure if this is the right way.
If the user is a developer, then
Have a screen where he/she can register an application. This will generate an API key/secret pair.
To access his/her own data (For 2 legged Auth) have a UI screen where the user can generate a access token for one his registered applications. He can specify the scopes and duration in the form.
If he is a 3rd party developer, then he needs to pass his applications API key to the person on whose behalf he needs to access the API and get an access token in exchange.
If the user wants a another application/developer to access API's on his behalf then
Have a screen where he can enter the third party's API key, scopes and the duration of the authorization. He can pass the generated access token to the developer who'll access the API's
I am going to use same OAuth libraries to generate the token that I would have used if I had gone the web service route. Further, I can also develop services whenever the current situation doesn't scale or the need arises and the existing tokens would still work.
The problem is mainly one of security. By design, duration of access token should not be set by a client. If someone else gets to know the access token and client id during this duration, this user's account will be compromised. Normally this duration is set to be not very long and a second secret value refresh token is used to refresh the current access token. The token refreshing can be automated in code, but in your approach it will need to be done manually.
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).