集成AspNetCore.Identity后Azure AD SSO失效,如何优先启用SSO?
解决方案:Azure AD SSO优先+AspNetCore.Identity身份管理整合
问题根源:AddIdentity会默认将Cookie认证方案(IdentityConstants.ApplicationScheme)设为默认的认证/挑战方案,覆盖了Azure AD的OpenID Connect方案,导致SSO登录被拦截。以下是具体解决步骤:
1. 调整Program.cs服务注册与认证配置
修改认证方案的默认规则,让Azure AD作为未认证时的默认挑战方案,同时保留Identity的Cookie作为登录后的默认认证方案:
// 1. 先注册Identity服务 builder.Services.AddIdentity<MyTUser, MyTRole>() .AddEntityFrameworkStores<MyContext>() .AddDefaultTokenProviders() .AddDefaultUI(); // 不需要Identity自带UI可移除 // 2. 配置认证规则,明确各场景的默认方案 builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme; // 登录后用Identity凭证 options.DefaultSignInScheme = IdentityConstants.ApplicationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; // 未认证时跳Azure SSO }) // 3. 添加Azure AD认证支持 .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) // 4. 显式声明Identity的Cookie方案(AddIdentity已默认添加,此处更清晰) .AddCookie(IdentityConstants.ApplicationScheme); // 5. 配置全局授权策略 builder.Services.AddRazorPages() .AddMvcOptions(options => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); options.Filters.Add(new AuthorizeFilter(policy)); }) .AddMicrosoftIdentityUI();
2. 处理Azure AD登录后的Identity用户同步
创建回调Action,在Azure AD登录成功后,匹配/创建EF Core Identity中的用户,并完成Identity登录流程:
using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Identity; using System.Security.Claims; public class AccountController : Controller { private readonly UserManager<MyTUser> _userManager; private readonly SignInManager<MyTUser> _signInManager; public AccountController(UserManager<MyTUser> userManager, SignInManager<MyTUser> signInManager) { _userManager = userManager; _signInManager = signInManager; } [AllowAnonymous] public async Task<IActionResult> AzureAdCallback() { // 获取Azure AD认证结果 var authResult = await HttpContext.AuthenticateAsync(OpenIdConnectDefaults.AuthenticationScheme); if (!authResult.Succeeded) { return RedirectToAction("Error", "Home"); } // 从Azure AD Claims中提取用户标识(这里用邮箱,可根据业务调整为ObjectId等) var email = authResult.Principal.FindFirstValue(ClaimTypes.Email); if (string.IsNullOrEmpty(email)) { return RedirectToAction("Error", "Home"); } // 查找或自动创建Identity用户 var identityUser = await _userManager.FindByEmailAsync(email); if (identityUser == null) { identityUser = new MyTUser { UserName = email, Email = email, EmailConfirmed = true // Azure AD登录可视为邮箱已验证 }; var createResult = await _userManager.CreateAsync(identityUser); if (!createResult.Succeeded) { return RedirectToAction("Error", "Home"); } } // 完成Identity登录 await _signInManager.SignInAsync(identityUser, isPersistent: false); // 清除Azure AD临时认证会话(可选) await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme); // 跳转至首页 return RedirectToAction("Index", "Home"); } }
3. 更新Azure AD应用注册配置
在Azure Portal的AD应用注册页面,将重定向URI修改为你的回调Action路径,例如:https://你的域名/Account/AzureAdCallback
核心逻辑说明
- 默认挑战方案设为Azure AD的OIDC,确保未认证用户首先跳转SSO登录页面
- 登录成功后同步到Identity用户,后续请求使用Identity的Cookie凭证,完全兼容AspNetCore.Identity的角色、权限、令牌管理等功能
- 若不需要自动创建用户,可将创建逻辑替换为跳转至用户绑定页面,引导用户关联已有Identity账号
内容的提问来源于stack exchange,提问作者MediocreFantasy
相关产品推荐
相关产品推荐

