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

ASP.NET Core 6中为Azure AD添加自定义Claim字段的技术问题

问题解答

1. 能否纯代码将UserID存入Azure AD认证Cookie?

完全可以,不需要Azure AD管理面板权限。ASP.NET Core的认证系统会把ClaimsPrincipal里的所有Claim存入本地生成的认证Cookie(不是Azure AD直接发放的Cookie,是本地维护的会话Cookie)。你只要在认证流程里添加自定义Claim,就会自动被包含到Cookie中,逻辑和之前Identity框架一致。

2. 该方案对SignalR是否可行?

非常适合SignalR。SignalR无法直接使用会话状态,但会自动携带认证Cookie,连接建立时ASP.NET Core会解析Cookie生成ClaimsPrincipal,你在Hub里可以直接通过Context.User.FindFirstValue("UserID")获取这个Claim,比会话方案更可靠,完全满足需求。

3. 解决OnTokenValidated事件中无法获取preferred_username的问题

你的代码里用context.HttpContext.User获取Claim是错误的,OnTokenValidated触发时,HttpContext.User还没完成初始化。正确做法是从context.Principal(由Azure AD的ID Token生成的认证主体)中获取,或者直接解析context.SecurityToken(ID Token)。

另外,代码还有两个优化点:

  • 别在事件处理器里直接创建SqlConnection,建议通过依赖注入获取数据服务或IDbConnection实例,符合ASP.NET Core设计规范。
  • 用异步方法避免阻塞线程,比如QueryFirstAsync替代QueryFirst。

修改后的代码示例:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    {
        builder.Configuration.Bind("AzureAd", options);
        options.Events = new OpenIdConnectEvents
        {
            OnTokenValidated = async context =>
            {
                // 从context.Principal获取preferred_username
                string signInEmailAddress = context.Principal.FindFirstValue("preferred_username");
                if (string.IsNullOrEmpty(signInEmailAddress))
                {
                    throw new InvalidOperationException("无法获取用户邮箱");
                }

                // 通过依赖注入获取数据库连接(推荐方式)
                var dbConnection = context.HttpContext.RequestServices.GetRequiredService<IDbConnection>();
                string query = "select dbo.A2F_0013_ReturnUserIDForEmail(@Email) as UserID";
                var queryResult = await dbConnection.QueryFirstAsync(query, new { Email = signInEmailAddress });

                // 添加自定义UserID Claim
                var appIdentity = new ClaimsIdentity(new[]
                {
                    new Claim("UserID", queryResult.UserID.ToString())
                });
                context.Principal.AddIdentity(appIdentity);
            },
        };
    })
    .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
    .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
    .AddInMemoryTokenCaches();

额外说明

  • 确保Azure AD的ID Token包含preferred_username:默认Azure AD会返回该Claim,如果没有,可在OpenIdConnectOptions中添加options.Scope.Add("profile"),因为preferred_username属于profile范围的Claim。
  • 自定义Claim会自动持久化到认证Cookie中,后续所有请求(包括SignalR连接)都能通过HttpContext.User或Hub.Context.User获取到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:30:54