我有一个解决方案,其中包括:
oidc-client
JavaScript库的React SPA Web应用程序。创建新用户时,我设置了一些自定义声明,这些声明保存在AspNetUserClaims
表中,如下所示:
然后,在我的API项目中,在控制器内部,我想获取已验证用户的那些用户声明。
我原以为this.User.Claims
会给我带来这些好处,但是相反,它返回的是以下内容,这些内容似乎与客户端应用程序有关,而不与用户有关。
如何从Web API项目内的控制器访问那些自定义用户声明(address, location, tenant_role
)?
切记,API项目无权访问UserManager
类或任何ASP.NET Identity Core
相关的东西。
答案 0 :(得分:1)
因此,我命令我的自定义用户声明在每个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
};
}
此方法将传递给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>();
通过该设置,每当API端点被命中时,都会显示我的自定义TenantRole
声明,因此我只需执行User.FindFirst(AnalyticsConstants.TenantRoleClaim)
就可以得到它。
答案 1 :(得分:0)
您将需要定义身份资源并定义la范围:
http://docs.identityserver.io/en/latest/topics/resources.html
然后确保它们由身份服务器中的IProfileService或IClaimsService实现公开:
http://docs.identityserver.io/en/latest/reference/profileservice.html
他们的声明可以包含在令牌本身中,也可以根据需要通过用户信息端点进行访问-如果您的声明数据特别大(即以1000个字符为单位),这是明智的选择。
答案 2 :(得分:-1)
您可以使用ClaimsPrincipal.FindFirst()
访问您的自定义声明。
示例:User.FindFirst("your_claim_key").Value
答案 3 :(得分:-1)
我编写了用于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;
}