【问题标题】:Azure Active Directory - MVC application best practices to store the access tokenAzure Active Directory - 存储访问令牌的 MVC 应用程序最佳实践
【发布时间】:2016-04-25 15:02:59
【问题描述】:

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

我需要查询 AAD Graph 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 存储为声明是否是一个好的解决方案(添加到 Startup 类中的行)?

context.AuthenticationTicket.Identity.AddClaim(new 
    Claim("OpenId_AccessToken", result.AccessToken));

EDIT Token 已存储..

得到它!谢谢乔治。 所以我的 Token 已经使用 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;
}

我从AuthenticationContext 不知道的: 如果令牌已被请求,它将从TokenDbCache 检索它。

【问题讨论】:

    标签: asp.net-mvc azure-active-directory azure-ad-graph-api


    【解决方案1】:

    当您通过 Adal 检索令牌时,它会将其缓存在 NaiveCache 对象中。

    使用 StartUp 类检索令牌的代码:

      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 示例 (https://github.com/AzureADSamples) 中,此对象用于在应用控制器中检索令牌。您可以实现自己的缓存以相同的方式检索它。

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

    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 方 api)获取令牌,您也可以将令牌存储在声明中

    【讨论】:

    • 我看到了示例,但我想知道为什么我需要实例化一个新的 AuthenticationContext ? AuthenticationContext 类中还有一个 AcquireTokenSilentAsync 方法。它是要向 AAD Graph API 发送一个新的 http 请求还是要尝试从 TokenCacheItem 获取值?
    • 当您调用 AcquireTokenSilentAsync 时,如果已使用缓存构造了 Context,它会尝试发送刷新令牌请求。请参阅github.com/AzureAD/azure-activedirectory-library-for-dotnet/… 中的实现
    猜你喜欢
    • 1970-01-01
    • 2018-03-24
    • 2012-08-02
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 2012-12-04
    • 2018-02-17
    • 1970-01-01
    相关资源
    最近更新 更多