Closed guardrex closed 9 years ago
Hi, the challenge here is that the token is obtained by a single use authorization code, which is processed when the first authentication takes place. The resulting token is placed in the cache, which is why the current code must work against the same cache in order to use the token in your own controllers when you want to actually call the service. If your code is truly one-shot, you could retrieve the access token as obtained in startup.auth.cs and make it available to your controllers using any other system. In that case, you don’t need to call acquiretokensilent from the controller. However I would discourage you to do so, given that it would trigger auth prompts far more often than necessary or would force you to re-implement complicated logic about deling with refresh tokens that you get for free when you use the cache as shown in the sample. HTH
hi @GuardRex. I don't know if it helps but I have been looking a lot at the WebApp-GroupClaims-DotNet sample and that, to me, has better commented code around the use of GraphApi. I felt I understood the token part of GraphApi ver 2 much better from this sample than on the WebApp-GraphAPI-DotNet sample. It uses a database to hold the token, which is scalable.
One minor note: For some strange reason they removed the code walkthrough from the README file from WebApp-GroupClaims-DotNet. I find that odd as I found the code walkthrough really useful to get an overview, and it includes talking about how the token is used. Here is a link to the original version with README in case you find that useful too.
Vittorio, Jon,
Thanks for the info and tips. As far as the Graph API helper class goes (NativeSessionCache.cs), I feel confident that I can simply store and retrieve the Graph API tokens by modifying the code in that helper class (e.g., use Azure dedicated caching to keep the tokens without ever needing to add a .NET session state provider to the app) ... but that's only a utility class for the Graph API, correct? Vittorio, you're hinting that the ADAL has .NET sessions baked into it's library, right? Therefore, I can't simply modify a few calls to the .NET session state as I can with the Graph API helper class.
If I'm right about that, then I think you are about to suggest that I setup an out-of-process session state provider for the app, such as SQL Server, Azure Caching, etc. This app (as many that I work with) span multiple instances, and this one just happens to be stateless (but still requires a login against AAD).
Jon, thanks for that tip ... I was able to get Graph API working fine without the token cache running, because I only call it once on login to get membership data for the app. I'll take a look at the GroupClaims example you reference.
It looks like the Group Claims example app is merely using application RAM to save its tokens, so it's even worse from a multi-instance standpoint. At least with the Graph API example, I can easily drop in an out-of-process session state provider and the utility helper class there will work unchanged (along with any session state calls that are baked into the ADAL API).
And I'll just briefly add that there are some great tips in the Group Claims example for:
--> An additional signout step to clear the token cache:
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
var authContext = new AuthenticationContext(ConfigHelper.Authority, new TokenDbCache(userObjectID));
authContext.TokenCache.Clear();
--> Additional handling for the redirect if the user should be sent back to a page that they weren't authorized to get when they first arrived:
if (redirectUri == null) redirectUri = "/";
HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties {RedirectUri = redirectUri}, OpenIdConnectAuthenticationDefaults.AuthenticationType);
Hi @GuardRex.
Glad your fixed on the token.
I don't suppose you need this but I was a bit puzzled when you said GroupClaims holds the token in memory. I did check and it holds the token in a database see TokenDbCache.
My apologies ... you are correct.
It looks like the token cache is running on session state. Can you provide some guidance for using the API with stateless apps (specifically when the session state mode is set to "Off" in Web.config)? I only need one-time access to AD for populating my app's membership; therefore, I don't need to cache tokens.
Can't I remove the statement for obtaining a
NaiveSessionCache
and take anAuthenticationContext
with the method that only requires theauthority
parameter? I understand that if I need to perform any other Graph API work, I'll need to get a new token.What about doing this when the request returns with a
Request.QueryString["reauth"] == "True"
and I need to send an OpenID Connect sign-in request to get a new set of tokens? Will having the session state (and the token cache) disabled cause a problem with that process?