如何在IdentityServer4中添加自定义声明来访问令牌? [已关闭]

问题描述 投票:0回答:4

我正在使用 IdentityServer4

我想添加其他自定义声明来访问令牌,但我无法执行此操作。我已经修改了 Quickstart5 并添加了 ASP.NET Identity Core 以及通过 ProfileService 的自定义声明,如 Coemgen below所建议的。

您可以在这里下载我的代码:[zip 包][3]。 (它基于:Quickstart5,带有 ASP.NET Identity Core 并通过 ProfileService 添加声明)。

问题:GetProfileDataAsync 不执行。

c# asp.net-core oauth-2.0 openid identityserver4
4个回答
121
投票

您应该实现自己的

ProfileService
。 看看我在实现同样的事情时遵循的这篇文章:

https://damienbod.com/2016/11/18/extending-identity-in-identityserver4-to-manage-users-in-asp-net-core/

这是我自己实现的一个例子:

public class ProfileService : IProfileService
{
    protected UserManager<ApplicationUser> _userManager;

    public ProfileService(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        //>Processing
        var user = await _userManager.GetUserAsync(context.Subject);

        var claims = new List<Claim>
        {
            new Claim("FullName", user.FullName),
        };

        context.IssuedClaims.AddRange(claims);
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        //>Processing
        var user = await _userManager.GetUserAsync(context.Subject);
        
        context.IsActive = (user != null) && user.IsActive;
    }
}

不要忘记在 Startup.cs 中配置服务(通过这个答案

services.AddIdentityServer()
    .AddProfileService<ProfileService>();

55
投票

好的,问题是这样的:

虽然您已经正确配置了可用身份资源(标准和自定义),但您还需要显式定义在调用api资源时哪些是必需的。为了定义它,您必须转到

Config.cs
项目上的
ExampleIdentityServer
类,并提供第三个参数,如
new ApiResouirce
构造函数。只有那些才会包含在
access_token

// scopes define the API resources in your system
public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("api1", "My API", new[] { JwtClaimTypes.Subject, JwtClaimTypes.Email, JwtClaimTypes.Phone, etc... })
    };
}

本质上,这意味着我为我的组织配置了身份声明,但可能涉及多个 API,并且并非所有 API 都使用所有可用的配置文件声明。这也意味着这些将出现在您的

ClaimsPrincipal
中,所有其余部分仍然可以通过“userinfo”端点作为正常的 http 调用进行访问。

注意:关于刷新令牌:

如果您选择通过

AllowOfflineAccess = true
启用刷新令牌,则在刷新 access_token 时可能会遇到相同的行为“GetProfileDataAsync 不执行!”。因此,尽管您获得了具有更新生命周期的新 access_token,但 access_token 内的声明保持不变。如果是这种情况,您可以通过在客户端配置上设置
UpdateAccessTokenClaimsOnRefresh=true
来强制它们始终从配置文件服务刷新。


45
投票

发现问题。

在startup.cs中,不要添加

services.AddTransient<IProfileService, ProfileService>();
,而是将
.AddProfileService<ProfileService>()
添加到
services.AddIdentityServer()

你最终会得到

services.AddIdentityServer()
    .AddTemporarySigningCredential()
    .AddInMemoryIdentityResources(Config.GetIdentityResources())
    .AddInMemoryApiResources(Config.GetApiResources())
    .AddInMemoryClients(Config.GetClients())
    .AddAspNetIdentity<ApplicationUser>()
    .AddProfileService<ProfileService>();

感谢 Coemgen 的帮助!代码没有问题,只是启动错误。


2
投票

您可以通过在配置类的 GetIdentityResources() 中使用 UserClaims 选项来包含任何声明:

用户索赔: 应包含在身份令牌中的关联用户声明类型的列表。 (根据官方文档)http://docs.identityserver.io/en/release/reference/identity_resource.html#refidentityresource

© www.soinside.com 2019 - 2024. All rights reserved.