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

Posted

技术标签:

【中文标题】如何在 IdentityServer4 中添加自定义声明以访问令牌? [关闭]【英文标题】:How to add custom claims to access token in IdentityServer4? [closed] 【发布时间】:2017-11-29 08:56:44 【问题描述】:

我正在使用IdentityServer4。

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

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

问题:GetProfileDataAsync 未执行。

【问题讨论】:

我对这个问题相当困惑,001。您显然是 Stack Overflow 的一位非常有经验的用户,但是您将代码放在文件柜而不是问题中,因此它——正如你必须知道的——离题了。您是否能够修复问题,使其不会被搁置? 【参考方案1】:

发现问题。

在 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 的帮助!代码没什么问题,只是启动出错了。

【讨论】:

这很有趣。您还应该能够使用 services.AddTransient(); . Microsoft Architecture GitHub 存储库中有一个很好的示例:github.com/dotnet-architecture/eShopOnContainers/blob/master/… @Coemgen 你也可以这样做!但您必须添加“ services.AddTransient();”在“services.AddIdentityServer()”之后:) 你可以简单地做这个 services.AddTransient();这将起作用 我相信如果你想坚持使用services.AddTransient&lt;IProfileService, ProfileService&gt;();,你应该在将身份服务器添加到服务之后这样做,这样你的注册就会覆盖 IS 所做的那个【参考方案2】:

您应该实现自己的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 中配置服务(通过 this answer)

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

【讨论】:

感谢您,但是,它仍然不起作用!未添加任何声明! 您是否在调试模式下定位 GetProfileDataAsync 函数? 我正在查看“安全”页面上的声明github.com/IdentityServer/IdentityServer4.Samples/blob/release/… 以 API 为目标时会发生什么?索赔是什么? 启动时会执行这个“services.AddTransient(); //AddClaims”但是断点,不执行GetProfileDataAsync方法【参考方案3】:

好的,这里的问题是:

虽然您已经正确配置了您的可用身份资源(标准和自定义),但您还需要明确定义在调用您的 api 资源时哪些是必需的。为了定义这一点,您必须转到 ExampleIdentityServer 项目上的 Config.cs 类并提供第三个参数,例如 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 来强制他们始终从 Profile Service 刷新。

【讨论】:

【参考方案4】:

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

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

【讨论】:

我试过了,不行! 我跟着这个,它不起作用! docs.identityserver.io/en/release/topics/…

以上是关于如何在 IdentityServer4 中添加自定义声明以访问令牌? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ClientCredentials grantType 向 IdentityServer4 生成的我的访问令牌添加声明

IdentityServer4 作为 Web API

如何使用 Identityserver4 添加/检查策略和角色 .net 核心 API 保护

游览结束后如何在 jourde 中添加自定义功能?

如何在 Laravel 5.3 中添加自定义通知通道

IdentityServer4 使用OpenID Connect添加用户身份验证