I've set up a simple MVC Application using Azure Active Directory(AAD).
I need to query the AAD Graph API in order to manage application roles and groups from my application.
In the Startup
class, I received the AccessToken like that:
public void ConfigureAuth(IAppBuilder app)
{
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = Constants.ClientId,
Authority = Constants.Authority,
PostLogoutRedirectUri = Constants.PostLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
// If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
var credential = new ClientCredential(Constants.ClientId, Constants.ClientSecret);
var signedInUserId =
context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
var authContext = new AuthenticationContext(Constants.Authority,
new TokenDbCache(signedInUserId));
var result = authContext.AcquireTokenByAuthorizationCode(
code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential,
Constants.GraphUrl);
var accessToken = result.AccessToken;
return Task.FromResult(0);
}
}
});
}
To instantiate the ActiveDirectoryClient
class, I need to pass the AccessToken :
var servicePointUri = new Uri("https://graph.windows.net");
var serviceRoot = new Uri(servicePointUri, tenantID);
var activeDirectoryClient = new ActiveDirectoryClient(serviceRoot,
async () => await GetTokenForApplication());
I am wondering if storing the AccessToken as a claim is a good solution (line to add in the Startup
class)?
context.AuthenticationTicket.Identity.AddClaim(new
Claim("OpenId_AccessToken", result.AccessToken));
EDIT Token is already stored..
Get it !!! Thank you George.
So my Token has been stored in the database using the TokenDbCache
class.
To get it again (in one of my controller) according to the sample:
public async Task<string> GetTokenForApplication()
{
string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
// get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
ClientCredential clientcred = new ClientCredential(clientId, appKey);
// initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID, new TokenDbCache<ApplicationDbContext>(signedInUserID));
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenSilentAsync(graphResourceID, clientcred, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
return authenticationResult.AccessToken;
}
What I don't know from the AuthenticationContext
:
If the token has already been requested, it is going to retrieve it from the TokenDbCache
.
When you are retrieving tokens through Adal it is caching it in NaiveCache object.
Code to retrieve token withing StartUp class:
In Azure Active Directory samples (https://github.com/AzureADSamples) this object utilized to retrieve token within app controllers. Youcan implement your own caching to retrieve it in a same manner.
In your controller code you can do following:
You can store token in claims as well if your are obtaining tokens not though AuthenticationContext (3d party apis)