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

我正在使用 IdentityServer4

我想添加其他自定义声明访问令牌,但我无法这样做。我修改了 Quickstart5,并按照 Coemgen 下面的建议,通过 ProfileService 添加了 ASP.NET 标识核心和自定义声明。

你可以在这里下载我的代码: [ zip package ][3]。(它基于: 快速启动5和 ASP.NET 标识核心,并通过 ProfileService 添加声明)。

问题: 未执行 GetProfileDataAsync。

75386 次浏览

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

用户声称: 应包含在标识标记中的关联用户声明类型的列表。(根据官方文档) < a href = “ http://docs.Identityserver.io/en/release/reference/Identity _ resource. html # refidtyresource”rel = “ nofollow noReferrer”> http://docs.identityserver.io/en/release/reference/identity_resource.html#refidentityresource

您应该实现自己的 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>();

发现问题。

在 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 的帮助! 代码没有问题,只是创业公司出了问题。

好吧,这里的问题是这样的:

虽然您已经正确地配置了 有空标识资源(标准和自定义) ,但是您还需要显式地定义 调用 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 服务刷新。