ASP.Net Identity with IdentityServer 无法在控制器上下文中获取用户

ASP.Net Identity with IdentityServer fails to get User in controller context

我遵循了文档 here 并且能够让我的控制器与 [Authorize] header 一起工作。我正在使用带有 ASP.NET 身份的 IdentityServer 作为我的用户存储。

在我的 ConfigureServices 我有:

services.AddIdentity<KipUser, IdentityRole>()
     .AddEntityFrameworkStores<KipDbContext>()
     .AddDefaultTokenProviders();

在我的 Configure 我有:

app.UseIdentityServer();
app.UseAuthorization();

并且在我的控制器中我做了一些测试:

[Authorize]
public IEnumerable<MyDTO> GetData(int count = 3) {
     var test = User; // The User.Identity.Name is empty for some reason
     var id = User.FindFirst(ClaimTypes.NameIdentifier).Value; // Successfully gets the Guid
     var test2 = _userManager.GetUserAsync(User); // result is null
     var test3 = _userManager.GetUserId(User); //returns null
     var test4 = _userManager.FindByIdAsync(id); // Successfully gets the User from the DB

似乎存在配置错误,因为 UserManager 未能从 ClaimsPrincipal User 变量中获取 ASP.Net 标识。我是否过于假设 .AddEntityFrameworkStores<KipDbContext>() 会将应用程序配置为知道如何 _userManager.GetUserAsync(User) 而不是我需要自己使用此 _userManager.FindByIdAsync(User.FindFirst(ClaimTypes.NameIdentifier).Value) 搜索声明?

您可以尝试将此添加到您的客户端。它修复了 Microsoft 认为的名称和 Identity Server 认为的名称声明之间的映射。

options.TokenValidationParameters = new TokenValidationParameters
{
    NameClaimType = JwtClaimTypes.Name,
    RoleClaimType = JwtClaimTypes.Role,
};

我问这个问题的主要原因是因为我看到很多关于 IdentityServer 2 和 3 的信息似乎相关。我无法让这些修复程序在我的 IdentityServer 4 项目中工作,所以我认为这是一个不同的问题。这是同一个问题。正如@Tore 指出的那样,这是声明的问题,但我认为这将通过 app.UseIdentityServer();

得到解决

This问题描述清楚:

UseIdentity and UserManager disagree on where the user ID claim is stored

尽管我们正在调用 app.UseIdentityServer();,但似乎有一些 Microsoft 安装的默认映射需要清除。

根据那个问题,在 app.UseIdentityServer(); 之前的 Startup.cs Configure 函数中添加 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); 为我解决了这个问题。我现在可以看到控制器中的声明没有改变,_userManager.GetUserAsync(User);_userManager.GetUserId(User); 都按预期工作。

令人惊讶的是,此函数调用未包含在 IdentityServerAspNetIdentity 示例项目中。