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

集成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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:05:59