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
示例项目中。
我遵循了文档 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
示例项目中。