You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 2.0中OpenID Connect的AdalDistributedTokenCache是什么?及Azure AD组声明实现

关于ASP.NET Core 2.0中AdalDistributedTokenCache与Azure AD组声明集成的解答

一、AdalDistributedTokenCache是什么?

AdalDistributedTokenCache是Azure AD认证库(ADAL)专为ASP.NET Core环境打造的分布式令牌缓存实现。

在单服务器部署场景下,默认的内存令牌缓存就能满足需求,但如果你的应用是多实例分布式部署(比如负载均衡后的多个节点),内存缓存就会出现令牌无法跨节点共享的问题——用户在A节点登录获取的令牌,切换到B节点请求时就找不到了,被迫重新认证。

这个组件的核心作用,就是把ADAL生成的访问令牌、刷新令牌等数据,存储到ASP.NET Core支持的分布式缓存系统中(比如Redis、SQL Server分布式缓存),让所有应用节点共享同一套令牌数据,同时自动处理令牌的过期、刷新逻辑,保证用户在分布式环境下的认证状态一致。

二、获取Azure AD用户组信息并集成到基于策略的授权步骤

下面是一步步落地你的需求的具体实现方案:

1. 配置OpenID Connect认证与必要权限

首先在Startup.cs的ConfigureServices中配置Azure AD的OpenID Connect认证,同时要确保你在Azure AD应用注册里添加了Microsoft Graph的Group.Read.All权限(需要管理员授予同意):

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.ClientId = "你的应用ClientId";
    options.ClientSecret = "你的应用ClientSecret";
    options.Authority = "https://login.microsoftonline.com/你的租户ID/v2.0";
    options.ResponseType = "code id_token";
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    // 添加读取用户组的Graph权限
    options.Scope.Add("https://graph.microsoft.com/Group.Read.All");
    options.SaveTokens = true; // 把令牌保存到Cookie,方便后续调用Graph使用
});

2. 授权码兑换令牌+调用Graph获取组信息

在OpenID Connect的OnAuthorizationCodeReceived事件中,完成授权码兑换访问令牌、调用Graph获取用户组,再把组信息转为声明的逻辑:

options.Events = new OpenIdConnectEvents
{
    OnAuthorizationCodeReceived = async context =>
    {
        // 从回调中拿到授权码
        var code = context.ProtocolMessage.Code;
        var credential = new ClientCredential(options.ClientId, options.ClientSecret);
        var authContext = new AuthenticationContext(options.Authority);
        
        // 用授权码兑换针对Microsoft Graph的访问令牌
        var tokenResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
            code,
            new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]),
            credential,
            "https://graph.microsoft.com/");

        // 初始化Graph客户端,用兑换到的令牌做认证
        var graphClient = new GraphServiceClient(
            new DelegateAuthenticationProvider(request =>
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.AccessToken);
                return Task.CompletedTask;
            }));
        
        // 调用Graph接口获取用户所属的组
        var userGroups = await graphClient.Me.MemberOf.Request().GetAsync();
        
        // 将组信息转为声明,添加到当前用户的身份凭证中
        var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
        foreach (var group in userGroups)
        {
            if (group is Group groupDetail)
            {
                // 这里可以用组名称作为Role声明,也可以用组ID自定义声明类型
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, groupDetail.DisplayName));
                // 示例:自定义声明类型存储组ID
                // claimsIdentity.AddClaim(new Claim("aad_group_id", groupDetail.Id));
            }
        }
        
        // 把令牌存入分布式缓存(如果启用了AdalDistributedTokenCache)
        var distributedCache = context.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();
        var tokenCache = new AdalDistributedTokenCache(distributedCache, new DistributedTokenCacheOptions());
        authContext.TokenCache = tokenCache;
        await tokenCache.SaveUserTokenCacheAsync(context.Principal, tokenResult.UserInfo.UniqueId);
    }
};

3. 配置基于组声明的授权策略

在ConfigureServices中添加自定义授权策略,关联刚才添加的组声明:

services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAdminGroup", policy =>
        policy.RequireClaim(ClaimTypes.Role, "管理员组"));
});

之后就可以在控制器或Action上使用这个策略做权限控制:

[Authorize(Policy = "RequireAdminGroup")]
public IActionResult AdminDashboard()
{
    return View();
}

4. 关键注意事项

  • 必须确保Azure AD应用已经获得Group.Read.All权限的管理员同意,否则调用Graph会返回权限不足的错误。
  • 如果要启用分布式缓存,需要先配置对应的服务,比如Redis:
    services.AddDistributedRedisCache(options =>
    {
        options.Configuration = "你的Redis连接字符串";
        options.InstanceName = "AppTokenCache";
    });
    
  • ASP.NET Core 2.0中ADAL是稳定兼容的,但如果后续有版本升级需求,可以考虑切换到MSAL(Microsoft Authentication Library)。

内容的提问来源于stack exchange,提问作者puri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:28:24