如何使自定义用户声明在API请求中可用

时间:2018-12-10 16:28:02

标签: c# asp.net identityserver4 claims-based-identity asp.net-identity-3

我有一个解决方案,其中包括:

  • 在ASP.NET Identity Core之上运行IdentityServer4的ASP.NET Core 2.1。
  • ASP.NET Core 2.1 Web API设置为使用IdentityServer作为身份验证提供程序。
  • 使用oidc-client JavaScript库的React SPA Web应用程序。

创建新用户时,我设置了一些自定义声明,这些声明保存在AspNetUserClaims表中,如下所示: enter image description here

然后,在我的API项目中,在控制器内部,我想获取已验证用户的那些用户声明。
我原以为this.User.Claims会给我带来这些好处,但是相反,它返回的是以下内容,这些内容似乎与客户端应用程序有关,而不与用户有关。

enter image description here

如何从Web API项目内的控制器访问那些自定义用户声明(address, location, tenant_role)?
切记,API项目无权访问UserManager类或任何ASP.NET Identity Core相关的东西。

4 个答案:

答案 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()访问您的自定义声明。

文档: https://docs.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal.findfirst?view=netcore-2.1

示例: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;
}