[英]How to make custom user claims be available in API requests
I have a solution consisting of: 我有一个解决方案包括:
oidc-client
javascript library. 使用oidc-client
javascript库的React SPA Web应用程序。 When I create new users I set some custom claims that are saved in the AspNetUserClaims
table which looks like this: 当我创建新用户时,我设置了一些保存在AspNetUserClaims
表中的自定义声明,如下所示:
Then, on my API project, inside a controller I want to get those user claims of the authenticated user. 然后,在我的API项目中,在控制器内部,我希望获得经过身份验证的用户的那些用户声明。
I was expecting this.User.Claims
to get me those, but instead that's returning the following, which seem to be claims related to the client app, not the user. 我期待着这个this.User.Claims
让我这些,但相反,它返回以下,这似乎是与客户端应用程序相关的声明,而不是用户。
How can I access those custom user claims ( address, location, tenant_role
) from a controller inside the Web API project? 如何从Web API项目中的控制器访问这些自定义用户声明( address, location, tenant_role
)?
Bare in mind that the API project doesn't have access to the UserManager
class or anything ASP.NET Identity Core
related. 请记住,API项目无权访问UserManager
类或与ASP.NET Identity Core
相关的任何内容。
So, I order for my custom user claim to be available in every API request I had to do the following when setting up the ApiResource
on the IdentityServer startup. 所以,我命令我的自定义用户声明在每个API请求中都可用,我在IdentityServer启动时设置ApiResource
时必须执行以下操作。
//Config.cs
public static IEnumerable<ApiResource> GetApiResources()
{
ApiResource apiResource = new ApiResource("api1", "DG Analytics Portal API")
{
UserClaims =
{
JwtClaimTypes.Name,
JwtClaimTypes.Email,
AnalyticsConstants.TenantRoleClaim // my custom claim key/name
}
};
return new List<ApiResource>
{
apiResource
};
}
This method is passed to the services.AddInMemoryApiResources
(or whatever storage method you're using) 此方法传递给services.AddInMemoryApiResources
(或您正在使用的任何存储方法)
IIdentityServerBuilder builder = services
.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
})
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources()) // here
.AddInMemoryClients(Config.GetClients())
.AddAspNetIdentity<ApplicationUser>();
With that setup, whenever an API endpoint is hit, my custom TenantRole
claim is present so I can simply do User.FindFirst(AnalyticsConstants.TenantRoleClaim)
to get it. 通过该设置,无论何时命中API端点,我的自定义TenantRole
声明都存在,因此我可以简单地执行User.FindFirst(AnalyticsConstants.TenantRoleClaim)
来获取它。
You'll need to define identity resources and scopes a la: 你需要定义身份资源和范围a:
http://docs.identityserver.io/en/latest/topics/resources.html http://docs.identityserver.io/en/latest/topics/resources.html
And then ensure that they are exposed by your IProfileService or IClaimsService implementation in your identity server: 然后确保它们由身份服务器中的IProfileService或IClaimsService实现公开:
http://docs.identityserver.io/en/latest/reference/profileservice.html http://docs.identityserver.io/en/latest/reference/profileservice.html
They claims can either be included in the tokens themselves or be access via the user info endpoint as needed - this is sensible if your claim data is particularly large (ie in the 1000s of characters). 它们声称可以包含在令牌中,也可以根据需要通过用户信息端点进行访问 - 如果您的声明数据特别大(即1000个字符),这是明智的。
You can use ClaimsPrincipal.FindFirst()
to access your customized claims. 您可以使用ClaimsPrincipal.FindFirst()
来访问您的自定义声明。
Doc: https://docs.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal.findfirst?view=netcore-2.1 Doc: https : //docs.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal.findfirst? view = netcore- 2.1
Example: User.FindFirst("your_claim_key").Value
示例: User.FindFirst("your_claim_key").Value
I wrote this extender for use in MVC 5 but since it uses the http context and system security (and not the User Manager or Identity) I assume the internals of this will work on MVC6 我编写了这个扩展程序用于MVC 5,但由于它使用了http上下文和系统安全性(而不是用户管理器或身份),我认为这种内部结构适用于MVC6
public static bool UserHasSpecificClaim(this HtmlHelper h, string claimType, string claimValue)
{
// get user claims
var user = HttpContext.Current.User as System.Security.Claims.ClaimsPrincipal;
if (user != null)
{
// Get the specific claim if any
return user.Claims.Any(c => c.Type == claimType && c.Value == claimValue);
}
return false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.