使用内置身份服务器在 asp net core 3.0 中添加和访问声明

Adding and accessing claims in asp net core 3.0 using built in Identity server

我目前无法解决索赔问题。我有一个 ASP.Net Core 3 项目,其中包含 angular 模板和存储在应用程序中的用户。

我想向我的用户添加声明,继续阅读我认为这很容易,只需按照

添加一些内容
await _UserManager.AddClaimAsync(user, new Claim(AccountStatic.ClaimTypes._Claim_Id, user.Id));

当您创建用户,然后在他们再次登录后使用以下行将其取回:

User.FindFirst(AccountStatic.ClaimTypes._Claim_Id)?.Value;

但这不起作用。我可以在我的数据库中看到正在写入 AspNetUserClaims table 的声明,但用户登录时声明中不存在。那里还有一些其他声明,但不是我添加的声明。

我是否需要在某处定义在登录时包含哪些用户声明?

编辑。 我发现 post 说明我需要使用 DI AddClaimsPrincipalFactory 添加声明。所以我添加了这个 class.

public class UserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
    public UserClaimsPrincipalFactory(UserManager<ApplicationUser> userManager,IOptions<IdentityOptions> optionsAccessor): base(userManager, optionsAccessor)
    {}

    //https://levelup.gitconnected.com/add-extra-user-claims-in-asp-net-core-web-applications-1f28c98c9ec6
    protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
    {
        var identity = await base.GenerateClaimsAsync(user);
        identity.AddClaim(new Claim(AccountStatic.ClaimTypes.Claim_Id, user.Id ?? "[no id]"));
        return identity;
    }
}

如果我单步执行代码,我可以看到这里添加的声明。但是在控制器中我的自定义声明不存在。

internal string GetUserId()
{
    if (User.Identity.IsAuthenticated == false)
        return null;

    return User.FindFirst(AccountStatic.ClaimTypes.Claim_Id)?.Value;
}

更新。 好吧,我觉得这很奇怪。我一直在尝试做其他人声称的工作,但对我来说,没有什么能让我得到用户名或 ID。检查 User 我得到以下信息。这里没有任何内容包含对登录用户的任何引用。

更新二: 只是注意到那里实际上有一个 Id:{http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: ed107a11-6c62-496b-901e-ed9e6497662a} 似乎是数据库中的用户 id。还不确定如何访问它。

这些return无效。

User.FindFirst(JwtRegisteredClaimNames.NameId)?.Value;
User.FindFirst("nameidentifier")?.Value;
User.FindFirst("NameIdentifier")?.Value;

另一个更新 我正在使用 UserClaimsPrincipalFactory 并断点它并查看声明我可以看到我想要的所有内容都在那里。但同样,如第一张图片所示,这些在我的 API 控制器中不可用。

我终于理解了这个问题,这在很大程度上要感谢 Ruard van Elburgs 的评论,以及他在链接问题 中所做的回答。

The problem is that the claims are not added to the access token. There are two tokens, the access token and the identity token. - Ruard van Elburg

他们理解发生了什么的关键是发现有两个令牌,并且它们包含不同的声明并具有不同的目的。

如果您认为有必要,您可以强制将一个令牌的声明也包含在另一个令牌中。

我的问题的解决方案是在 Startup.ConfigureServices

中添加这个
services
    .AddIdentityServer(options => {})
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
    {
        foreach (var c in options.ApiResources)
        {
            // the string name of the token I want to include
            c.UserClaims.Add(AccountStatic.ClaimTypes.Claim_Id); 
        }
    });

我仍然不知道如何获取身份令牌,但由于我现在将用户 ID 包含在访问令牌中,我的问题暂时得到解决。