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

在/connect/authorize调用时,带认证Cookie的Middleware获取User.Identity失败

问题分析与解决方案

核心问题出在中间件的注册顺序上:你的自定义中间件注册在了认证中间件(UseAuthentication())之前,导致请求还没经过认证流程解析Cookie,HttpContext.User就被访问了,所以始终为空。

解决步骤

  1. 调整中间件顺序
    必须确保UseAuthentication()和UseAuthorization()先于你的自定义中间件执行,这两个中间件负责解析认证Cookie并将用户身份信息填充到HttpContext.User中。

    示例Program.cs(.NET 6+ 顶级语句模式):

    var builder = WebApplication.CreateBuilder(args);
    
    // 注册认证服务(Cookie认证为例)
    builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            // 根据你的需求配置Cookie参数,比如过期时间、路径等
            options.Cookie.Name = "YourAuthCookieName";
        });
    builder.Services.AddAuthorization();
    
    // 注册其他服务...
    builder.Services.Configure<RegistrationBehavior>(builder.Configuration.GetSection(nameof(RegistrationBehavior)));
    
    var app = builder.Build();
    
    // 基础中间件
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    
    // 先执行认证和授权中间件
    app.UseAuthentication();
    app.UseAuthorization();
    
    // 再注册你的自定义中间件
    app.Use(async (httpContext, next) =>
    {
        // 先判断Identity是否存在,避免空引用异常
        if (httpContext.User.Identity?.IsAuthenticated == true)
        {
            var userId = httpContext.User.Claims.FirstOrDefault(x => x.Type == "sub")?.Value;
            var isRedirectClaim = httpContext.User.Claims.FirstOrDefault(x => 
                x.Type == Admin.BusinessLogic.Identity.Dtos.Enums.Key4ClaimTypes.IsRedirect.ToString());
    
            if (isRedirectClaim == null || isRedirectClaim.Value.ToLower() != "true")
            {
                var registrationBehavior = httpContext.RequestServices.GetRequiredService<IOptions<RegistrationBehavior>>().Value;
                var reqUrl = Microsoft.AspNetCore.Http.Extensions.UriHelper.GetEncodedUrl(httpContext.Request);
                // 用ASP.NET Core原生的Uri.EscapeDataString替代System.Web的API
                var returnUrl = $"{registrationBehavior.PageRedirectUrl}?identityUserId={userId}&returnUrl={Uri.EscapeDataString(reqUrl)}";
    
                httpContext.Response.Redirect(returnUrl);
                // 重定向后直接返回,无需继续执行后续中间件
                return;
            }
        }
    
        await next();
    });
    
    app.MapControllers();
    app.Run();
    
  2. 额外优化点

    • 访问Identity.IsAuthenticated前先判断Identity是否为null,避免NullReferenceException
    • 重定向完成后直接return,不要调用next(),防止后续中间件不必要的执行
    • 替换System.Web.HttpUtility.UrlEncode为Uri.EscapeDataString,ASP.NET Core中不推荐使用System.Web组件
    • 用IOptions<RegistrationBehavior>获取配置,更符合依赖注入的最佳实践
  3. 验证认证流程
    确认登录时生成的ClaimsIdentity中确实包含了sub和IsRedirect声明,且Cookie的配置(如名称、域、路径)与认证中间件的配置一致,避免Cookie无法被正确解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:55:27