Asp.net mvc Azure Active Directory-存储访问令牌的MVC应用程序最佳实践

Asp.net mvc Azure Active Directory-存储访问令牌的MVC应用程序最佳实践,asp.net-mvc,azure-active-directory,azure-ad-graph-api,Asp.net Mvc,Azure Active Directory,Azure Ad Graph Api,我已经使用Azure Active Directory(AAD)设置了一个简单的MVC应用程序 我需要查询AAD图形API,以便从我的应用程序管理应用程序角色和组 在Startup类中,我收到如下AccessToken: public void ConfigureAuth(IAppBuilder app) { AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier; app.SetDefau

我已经使用Azure Active Directory(AAD)设置了一个简单的MVC应用程序

我需要查询AAD图形API,以便从我的应用程序管理应用程序角色和组

Startup
类中,我收到如下AccessToken:

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);
                }
            }
        });
}
要实例化
ActiveDirectoryClient
类,我需要传递AccessToken:

var servicePointUri = new Uri("https://graph.windows.net");
var serviceRoot = new Uri(servicePointUri, tenantID);
var activeDirectoryClient = new ActiveDirectoryClient(serviceRoot,
        async () => await GetTokenForApplication());
我想知道将AccessToken存储为声明是否是一个好的解决方案(添加到
启动
类中的行)

编辑令牌已存储。

明白了!!!谢谢你,乔治。 因此,我的令牌已使用
TokenDbCache
类存储在数据库中

要根据示例再次获取它(在我的一个控制器中):

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;
}
public异步任务GetTokenForApplication()
{
字符串signedInUserID=ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
字符串tenantID=ClaimsPrincipal.Current.FindFirst(“http://schemas.microsoft.com/identity/claims/tenantid1.价值;
字符串userObjectID=ClaimsPrincipal.Current.FindFirst(“http://schemas.microsoft.com/identity/claims/objectidentifier1.价值;
//在不触发任何用户交互的情况下获取图形的令牌(从缓存,通过多资源刷新令牌等)
ClientCredential clientcred=新的ClientCredential(clientId,appKey);
//使用保存在应用程序数据库中的当前登录用户的令牌缓存初始化AuthenticationContext
AuthenticationContext AuthenticationContext=新的AuthenticationContext(aadInstance+tenantID,新的TokenDbCache(SignedUserID));
AuthenticationResult AuthenticationResult=等待authenticationContext.AcquireTokenSilentAsync(graphResourceID,clientcred,新用户标识符(userObjectID,UserIdentifierType.UniqueId));
返回authenticationResult.AccessToken;
}
身份验证上下文中我不知道的内容

如果已经请求了令牌,则当您通过Adal检索令牌时,它将从
TokenDbCache

中检索令牌,并将其缓存在NaiveCache对象中

使用启动类检索令牌的代码:

  AuthenticationResult kdAPiresult = authContext.AcquireTokenByAuthorizationCode(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, "Your API Resource ID");
                            string kdAccessToken = kdAPiresult.AccessToken;
在Azure Active Directory示例()中,此对象用于在应用程序控制器中检索令牌。您可以实现自己的缓存,以同样的方式检索它

在控制器代码中,您可以执行以下操作:

IOwinContext owinContext = HttpContext.GetOwinContext();
                string userObjectID = owinContext.Authentication.User.Claims.First(c => c.Type == Configuration.ClaimsObjectidentifier).Value;
                NaiveSessionCache cache = new NaiveSessionCache(userObjectID);
                AuthenticationContext authContext = new AuthenticationContext(Configuration.Authority, cache);
                TokenCacheItem kdAPITokenCache = authContext.TokenCache.ReadItems().Where(c => c.Resource == "You API Resource ID").FirstOrDefault();

如果您不是通过AuthenticationContext(3d party API)获取令牌,那么您也可以在声明中存储令牌。

我看到了示例,但我想知道为什么需要实例化一个新的AuthenticationContext?AuthenticationContext类中还有一个AcquireTokenSilentAsync方法。它是要向AAD Graph API发送一个新的http请求,还是要尝试从TokenCacheItem获取值?当您调用AcquireTokenSilentAsync时,如果已使用缓存构造上下文,它将尝试发送刷新令牌请求。请参阅中的实现
IOwinContext owinContext = HttpContext.GetOwinContext();
                string userObjectID = owinContext.Authentication.User.Claims.First(c => c.Type == Configuration.ClaimsObjectidentifier).Value;
                NaiveSessionCache cache = new NaiveSessionCache(userObjectID);
                AuthenticationContext authContext = new AuthenticationContext(Configuration.Authority, cache);
                TokenCacheItem kdAPITokenCache = authContext.TokenCache.ReadItems().Where(c => c.Resource == "You API Resource ID").FirstOrDefault();