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

时间:2017-06-26 13:36:57

标签: c# asp.net-core oauth-2.0 openid identityserver4

我正在使用IdentityServer4

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

您可以在此处下载我的代码:[zip package] [3]。 (它基于:Quickstart5与ASP.NET Identity Core,并通过ProfileService添加声明。

问题:GetProfileDataAsync未执行。

4 个答案:

答案 0 :(得分:41)

您应该实现自己的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.AddTransient<IProfileService, ProfileService>();

答案 1 :(得分:24)

好的问题是:

虽然您已正确配置可用身份资源(标准和自定义),但您还需要明确定义在调用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内,其余所有内容仍然可以通过&#34; userinfo&#34;端点作为普通的http呼叫。

注意:关于刷新令牌:

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

答案 2 :(得分:16)

发现问题。

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

添加&#34; .AddProfileService()&#34;到services.AddIdentityServer()

你最终会得到

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

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

答案 3 :(得分:2)

您可以在config类的GetIdentityResources()中使用UserClaims选项包含任何声明:

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