ASP.NET Core中扩展AD用户及SSO认证方案咨询
解决方案梳理
一、SSO与无注册访问的落地方式
既然你已经通过Microsoft Identity Platform实现了SSO登录,结合内网场景,直接基于**企业本地AD同步到Azure AD(或IT团队维护的Azure AD租户)**作为身份源是最优选择:
- 无需用户注册:所有已在企业AD的员工,只要同步到Azure AD(或已存在于Azure AD租户中),就能直接通过SSO访问应用,完全省略手动注册流程。
- 无需管理用户:用户的创建、密码重置、账号生命周期全由负责AD的IT团队维护,你仅需接收认证后的用户唯一标识即可。
二、避免Identity重复存储用户的两种方案
你完全不需要用ASP.NET Core Identity来处理用户注册、密码管理,以下两种轻量方式更适配你的需求:
1. 纯Claims认证+自定义用户表
直接跳过Identity框架,只保留认证中间件,流程如下:
- 配置Microsoft Identity Platform认证中间件,用户登录后从Token中提取全局唯一标识(比如
oid或upn,这两个是Azure AD返回的用户唯一ID)。 - 创建独立的自定义用户扩展表,结构示例:
CREATE TABLE UserExtensionInfo ( UserUniqueId NVARCHAR(255) PRIMARY KEY, -- 关联Azure AD的oid/upn Role NVARCHAR(50), AllowedPaths NVARCHAR(MAX), -- 可存储JSON格式的路径列表 -- 其他业务需要的自定义字段 ) - 用户登录成功后,用
UserUniqueId查询自定义表,将角色、访问路径等信息加入用户的Claims集合,供后续授权逻辑使用。 - 授权直接基于Claims判断,比如检查
RoleClaim是否匹配,或AllowedPaths是否包含当前请求路径。
2. 保留Identity但禁用用户管理功能
如果想借助Identity的角色授权、Claims管理能力,可做如下配置:
- 自定义
ApplicationUser类,仅保留核心关联字段(比如Id绑定Azure AD的oid),移除密码、邮箱等不需要的字段。 - 配置Identity时禁用注册、密码相关功能:
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = false) .AddEntityFrameworkStores<ApplicationDbContext>(); // 禁用密码规则、注册相关约束 services.Configure<IdentityOptions>(options => { options.User.RequireUniqueEmail = false; options.Password.RequireDigit = false; options.Password.RequiredLength = 0; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequireLowercase = false; }); - 用户首次登录时,自动创建仅含
Id的Identity用户,后续登录直接关联。这样既利用Identity的授权体系,又无需手动管理用户账号和密码。
三、获取特定角色用户列表的方法
由于角色信息存在你的自定义表中,直接执行SQL查询即可:
SELECT UserUniqueId FROM UserExtensionInfo WHERE Role = 'Admin'
如果需要获取用户的AD原生信息(如姓名、部门),可通过Microsoft Graph API,用UserUniqueId(即oid)作为筛选条件,调用接口拉取对应数据。
四、Microsoft Identity Platform与自定义表结合的具体步骤
- Azure应用注册配置:确保Azure AD中的应用注册设置为允许企业内网用户访问(单租户模式,或包含同步的本地AD用户)。
- 认证中间件配置:在.NET Core项目中配置Microsoft Identity认证,获取用户唯一标识:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")); - 自定义表关联逻辑:在Token验证通过的事件中,查询自定义表并注入扩展Claims:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(options => { Configuration.Bind("AzureAd", options); options.Events = new OpenIdConnectEvents { OnTokenValidated = async context => { var userId = context.Principal.FindFirstValue(ClaimTypes.NameIdentifier); // 从自定义表查询扩展信息 var userExt = await _userExtensionRepo.GetByUserIdAsync(userId); if (userExt != null) { var identity = context.Principal.Identity as ClaimsIdentity; identity.AddClaim(new Claim("Role", userExt.Role)); identity.AddClaim(new Claim("AllowedPaths", userExt.AllowedPaths)); } } }; }); - 授权逻辑实现:在API或页面中,使用
[Authorize(Roles = "Admin")]或自定义授权策略,基于Claims完成权限校验。
内容的提问来源于stack exchange,提问作者Ryan Farahani
相关产品推荐
相关产品推荐

