如何在IdentityServer4中添加自定义声明来访问令牌?

001*_*001 39 c# openid oauth-2.0 asp.net-core identityserver4

我正在使用IdentityServer4.

我想添加其他自定义声明来访问令牌,但我无法做到这一点.我修改了Quickstart5,并按照下面的Coemgen的建议,通过ProfileService添加了ASP.NET Identity Core和自定义声明.

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

问题:GetProfileDataAsync未执行.

Ble*_*ill 51

您应该实现自己的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

}

不要忘记在Startup.cs中添加此行

services.AddTransient<IProfileService, ProfileService>();
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,但是,它仍然不起作用!没有添加任何声明! (3认同)

cle*_*ris 25

好的问题是:

虽然您已正确配置了可用的 Identity资源(标准和自定义),但您还需要在调用api资源明确定义哪些是必需的.为了定义它,你必须Config.csExampleIdentityServer项目上去你的类,并在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... })
    };
}
Run Code Online (Sandbox Code Playgroud)

实质上,这意味着我获得了为我的组织配置的身份声明,但可能涉及多个API,并非所有API都使用所有可用的配置文件声明.这也意味着这些将存在于您的ClaimsPrincipal所有其余内容仍然可以通过"userinfo"端点作为普通的http调用访问.

注意:关于刷新令牌:

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


001*_*001 20

发现问题.

在startup.cs中,而不是添加"services.AddTransient();"

将".AddProfileService()"添加到services.AddIdentityServer()

你最终会得到

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

感谢Coemgen的帮助!代码没有错,只是启动错了.

  • Microsoft Architecture GitHub存储库有一个很好的例子:https://github.com/dotnet-architecture/eShopOnContainers/blob/master/src/Services/Identity/Identity.API/Startup.cs (3认同)
  • 这很有趣。您还应该能够使用 services.AddTransient&lt;IProfileService, ProfileService&gt;(); . (2认同)
  • @Coemgen 你也可以这样做!但您必须添加“ services.AddTransient&lt;IProfileService, ProfileService&gt;();” 在“services.AddIdentityServer()”之后:) (2认同)