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

Azure AD登录关联失败排查及用户登录数据获取咨询

问题描述

我尝试通过HTTP协议对接Azure AD实现登录并获取已登录用户的数据,但在配置应用认证后出现错误:Exception: An error was encountered while handling the remote login. Correlation failed。以下是Startup中的配置服务及中间件代码:

services.AddDistributedMemoryCache();
services.AddSession(options =>
{
    options.Cookie.Name = "data"; // Set your session cookie name
    options.IdleTimeout = TimeSpan.FromMinutes(30); // Set session timeout
    options.Cookie.IsEssential = true; // Essential for authentication
});

// Cookie Authentication and OpenID Connect setup (if needed)
services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
    options.Cookie.Name = "AuthCookie";
    options.Cookie.HttpOnly = true;
    options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
    options.SlidingExpiration = true;
    options.Cookie.SameSite = SameSiteMode.Lax;
    
})
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Authority = "https://login.microsoftonline.com/****************/";
    options.ClientId = "**************";
    options.ClientSecret = "******************";
    options.ResponseType = "code";
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
    options.CallbackPath = "/en/masterbom";
    options.SaveTokens = true;

    options.Events.OnTicketReceived = async context =>
    {
        var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
        if (claimsIdentity != null)
        {
            // Modify or add claims if needed
        }
    };
});


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionHandler();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }
    app.UseStaticFiles();

    app.UseRouting();

    app.UseSession();
    app.UseAuthentication();     
}

请问如何修复该错误并获取已登录用户的数据?


修复方案及用户数据获取指南

一、解决"Correlation failed"错误

该错误多由中间件顺序错误、重定向URI不匹配、Cookie配置冲突导致,按以下步骤修复:

1. 修正中间件执行顺序

Configure方法必须添加UseAuthorization,且严格遵循中间件执行顺序:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts(); // 生产环境建议启用HTSTS
    }
    app.UseStaticFiles();

    app.UseRouting();

    app.UseSession();
    app.UseAuthentication();
    app.UseAuthorization(); // 必须添加,且位于UseAuthentication之后

    // 添加端点路由配置(MVC/Razor Pages必备)
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

2. 匹配Azure AD重定向URI

登录Azure Portal,找到你的应用注册,在认证页面的"重定向URI"中,添加与代码中options.CallbackPath完全一致的地址。例如代码中是/en/masterbom,则添加http://localhost:5000/en/masterbom(开发环境)或生产环境的对应HTTPS地址。

3. 调整OIDC关联Cookie配置

在AddOpenIdConnect中补充关联Cookie的配置,避免同站/跨域问题:

.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    // 保留原有配置...
    
    // 配置关联Cookie
    options.CorrelationCookie.SameSite = SameSiteMode.Lax;
    options.CorrelationCookie.HttpOnly = true;
    // 开发环境HTTP下允许非安全Cookie(生产必须用HTTPS,设为SameAsRequest)
    if (env.IsDevelopment())
    {
        options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.None;
    }
})

4. 移除不必要的Session配置(可选)

OIDC本身会处理关联逻辑,若业务不需要Session,可移除AddDistributedMemoryCache()和AddSession()相关代码,避免Cookie冲突。

二、获取已登录用户数据

1. 通过ClaimsPrincipal直接获取基础信息

在控制器中,使用User属性访问用户的声明信息:

public IActionResult UserProfile()
{
    // 获取Azure AD对象ID(用户唯一标识)
    var userId = User.FindFirstValue("oid");
    // 获取用户名
    var userName = User.FindFirstValue(ClaimTypes.Name);
    // 获取邮箱
    var email = User.FindFirstValue(ClaimTypes.Email);
    // 获取用户名字
    var givenName = User.FindFirstValue(ClaimTypes.GivenName);

    // 可将数据传递给视图或业务逻辑
    return View(new { UserId = userId, UserName = userName, Email = email });
}

2. 在OnTicketReceived事件中扩展用户数据

利用已有的OnTicketReceived事件,可添加自定义声明或调用Microsoft Graph API获取更多用户信息:

options.Events.OnTicketReceived = async context =>
{
    var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
    if (claimsIdentity != null)
    {
        // 添加自定义声明
        var tenantId = context.Principal.FindFirstValue("tid");
        claimsIdentity.AddClaim(new Claim("TenantId", tenantId));

        // 调用Microsoft Graph API获取详细用户数据(需添加Graph SDK依赖)
        var accessToken = await context.HttpContext.GetTokenAsync("access_token");
        // var graphClient = new GraphServiceClient(
        //     new DelegateAuthenticationProvider(req =>
        //     {
        //         req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        //         return Task.CompletedTask;
        //     }));
        // var userDetails = await graphClient.Me.Request().GetAsync();
        // 可将Graph返回的信息添加为声明
    }
};

3. 在Razor视图中展示用户数据

直接在视图中使用User对象读取信息:

<div class="user-info">
    <p>当前登录用户:@User.Identity.Name</p>
    <p>邮箱:@User.FindFirstValue(ClaimTypes.Email)</p>
    <p>租户ID:@User.FindFirstValue("tid")</p>
</div>

额外排查建议

  • 开发环境使用HTTP时,确保Azure AD应用注册允许HTTP重定向URI(生产环境强制HTTPS)。
  • 开启调试日志排查细节:在appsettings.json中添加日志配置,查看认证过程的详细错误:
{
  "Logging": {
    "LogLevel": {
      "Microsoft.AspNetCore.Authentication": "Debug",
      "Microsoft.AspNetCore.Authentication.OpenIdConnect": "Debug"
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:40:55