【问题标题】:HttpContext User claims are emptyHttpContext 用户声明为空
【发布时间】:2021-04-13 16:34:35
【问题描述】:

我之前有一个使用 IdentityServer 和 .Net Core 2.2 的工作项目

我最近将项目的 .Net 版本从 Core 2.2 升级到 .Net 5。还将每个包更新到最新版本。对我的代码进行了一些调整,最终摆脱了所有错误。我正在我的 WEB API 上测试我的身份服务器功能,由于某种原因,HttpContext.User.Claims 返回空。

这是我的代码。

public Guid? CurrentUserId
{
    get
    {

       var claimNameIdentifier = User.Claims.FirstOrDefault(a => a.Type == ClaimTypes.NameIdentifier)?.Value;
       return claimNameIdentifier != null ? Guid.Parse(claimNameIdentifier) : (Guid?)null;
    }
}

我在一个基本控制器上有这个,由我的端点控制器实现,以获取访问我的端点的 JWT 上的用户 ID。不确定这是否是由于之前的更新。

这是我的身份服务器的配置

public static IEnumerable<IdentityResource>  IdentityResources =>
        new List<IdentityResource>
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile()
        };
    public static IEnumerable<ApiResource> ApiResources =>
       new List<ApiResource>
       {
           new ApiResource
            {
               Name = "ssi.api",
               DisplayName = "Standing Settlement Instructions API"
            }
       };

    public static IEnumerable<ApiScope> ApiScopes =>
        new List<ApiScope>
        {
            new ApiScope
            {
               Name = "ssi.api",
               DisplayName = "Standing Settlement Instructions API"
            
            }
        };

    public static IEnumerable<Client> Clients =>
        new List<Client>
        {
            new Client
            {
                ClientId = "ssi.front",
                ClientName = "SSI Client",
                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                // secret for authentication
                ClientSecrets =
                {
                   new Secret("my secret".Sha256())
                },
                // scopes that client has access to
                AllowedScopes = {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "ssi.api",
                    JwtClaimTypes.Role
                },
                AccessTokenLifetime = 14400,
                AllowOfflineAccess = true,
            }
        };

这是我的 ConfigureServices 的样子:

// Database
   services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer("Server=localhost; Database = SsiDB; Integrated Security = SSPI; MultipleActiveResultSets=true;"));
    #region Identity
    services.AddIdentity<User, Role>(options =>
    {
        options.Password.RequiredLength = 8;
        options.Password.RequireDigit = false;
        options.Password.RequireLowercase = false;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequireUppercase = false;
        options.User.RequireUniqueEmail = true;
    })
    .AddRoles<Role>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

    var identityBuilder = services.AddIdentityServer()
        .AddInMemoryPersistedGrants()
        .AddInMemoryClients(IdentityConfig.Clients)
        .AddInMemoryApiResources(IdentityConfig.ApiResources)
        .AddInMemoryApiScopes(IdentityConfig.ApiScopes)
        .AddAspNetIdentity<User>();

    identityBuilder.Services.AddTransient<IResourceOwnerPasswordValidator, OwnerPasswordValidator>();
    identityBuilder.Services.AddTransient<IProfileService, IdentityProfileService>();
    identityBuilder.AddSigningCredential(new X509Certificate2("StandingSettlementInstructionsIdentityAuth.pfx", "", X509KeyStorageFlags.MachineKeySet)); //release
    #endregion

    services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = appSettings.ApiUrl;
        options.Audience = "ssi.api";
        options.RequireHttpsMetadata = false;
    });

这是我的配置

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
        app.UseHsts();
        string appDataPath = Directory.GetCurrentDirectory() + @"\AppData";

        if (!Directory.Exists(appDataPath))
            Directory.CreateDirectory(appDataPath);

        app.UseSwaggerUI(o =>
        {
            o.DocumentTitle = "Standing Settlement Instructions Api Documentation";
            o.RoutePrefix = "api-docs";
            o.SwaggerEndpoint("/swagger/v1/swagger.json", "Version 1");
        });
        app.UseSwagger();

        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseCors("CorsPolicy");
        app.UseIdentityServer();
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<NotificationHubService>("/NotificationHubService");
        });

        app.Run((context =>
        {
            context.Response.Redirect("api-docs");
            return Task.CompletedTask;
        }));
    }

我尝试过的事情:

  • 在 ConfigureService services.AddSingleton&lt;IHttpContextAccessor, HttpContextAccessor&gt;(); 上添加了它,并在我的基本控制器上使用它。结果相同
  • 根据一些谷歌搜索重新安排对 Configure 方法的调用
  • 添加了关于 API 资源和 API 范围的声明。结果相同

一些观察。访问 localhost/.well-known/openid-configuration 会显示支持的空声明,当我在 API 资源或 API 范围上添加声明时,它确实出现在那里,但在提取声明时仍然遇到相同的问题。还是空的。

任何帮助将不胜感激。一直在拉我的头发。谢谢!

【问题讨论】:

    标签: c# .net identityserver4 .net-5


    【解决方案1】:

    调试声明问题的第一步是实际查看访问令牌实际包含什么?使用像 https://jwt.io/ 这样的工具来做到这一点。

    那么微软和IdentityServer对声明的名称应该是什么意见不同,所以需要指出,哪个声明是名称声明,通过使用:

        .AddJwtBearer(opt =>
        {
            opt.TokenValidationParameters.RoleClaimType = "roles";
            opt.TokenValidationParameters.NameClaimType = "name";
    
            ...
    

    【讨论】:

    • 将在我的帖子中添加我的 jwt 内容。但我可以确认存在正确的声明以及我添加的一些自定义声明。我会尝试这种方法并让你知道。谢谢!
    • 为了让您的生活更轻松,我建议将 IdentityServer 托管在它自己的“服务”中。否则会更难调试。
    • 您的问题解决了吗?如果它回答了您的问题,请随时接受答案
    • 不幸的是,它没有。我决定恢复到旧版本的 .Net 以使其同时工作。至少我赞成这个答案。
    • 很遗憾,您不得不返回,如果您想再试一次,请随时发布新问题。为“声明转换”做谷歌,因为这就是为什么来自访问令牌的声明没有最终出现在用户对象中的问题。
    猜你喜欢
    • 2021-03-25
    • 2018-04-25
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 2021-12-25
    • 2021-08-06
    • 1970-01-01
    • 2019-12-23
    相关资源
    最近更新 更多