【问题标题】:Check user claims during request in ASP .NET Core Web API在 ASP .NET Core Web API 请求期间检查用户声明
【发布时间】:2019-01-19 02:31:44
【问题描述】:

我在Startup.cs中定义了策略:

services.AddAuthorization(options =>
{
    options.AddPolicy(PolicyTypes.Engines.Get, policy =>
    {
        policy.RequireClaim(CustomClaimTypes.Permission, Permissions.Engines.Get);
    });
    options.AddPolicy(PolicyTypes.Engines.Manage, policy =>
    {
        policy.RequireClaim(CustomClaimTypes.Permission, Permissions.Engines.Manage);
    });
});

权限类:

public static class Permissions
    {
        public static class Engines
        {
            public const string Manage = "engines.manage";
            public const string Get = "engines.get";
        }
}

后来我用定义的策略在控制器中实现了端点。

[Authorize(Policy = PolicyTypes.Engines.Get)]
[HttpGet(Name = "Engines")]
public IEnumerable<Engine> GetAll()
{
    IEnumerable<Engine> engines = repository.GetAll<Engine>();
    return engines;
}

我通过邮递员使用 Bearer 令牌进行测试,以检查对该端点的访问。测试用户有策略PolicyTypes.Engines.Manage。解码令牌的结果。

{
  "sub": "test@test.com",
  "email": "test@test.com",
  "claims": [
    {
      "Issuer": "LOCAL AUTHORITY",
      "OriginalIssuer": "LOCAL AUTHORITY",
      "Properties": {},
      "Subject": null,
      "Type": "projectname/permission",
      "Value": "engines.manage",
      "ValueType": "http://www.w3.org/2001/XMLSchema#string"
    },
    {
      "Issuer": "LOCAL AUTHORITY",
      "OriginalIssuer": "LOCAL AUTHORITY",
      "Properties": {},
      "Subject": null,
      "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
      "Value": "Constructor",
      "ValueType": "http://www.w3.org/2001/XMLSchema#string"
    }
  ],
  "iss": "dotnet_TEST",
  "aud": "TEST",
  "nbf": 1534023667,
  "iat": 1534023667,
  "exp": 1534027267
}

当我执行请求时,我得到代码 200 和结果 json 表单端点。我没有得到 403 禁止的原因是什么?

我提供生成令牌的代码。

private async Task<List<Claim>> GetValidClaims(User user)
        {
            IdentityOptions _options = new IdentityOptions();
            var claims = new List<Claim>
        {
            new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
            new Claim(JwtRegisteredClaimNames.Jti, await options.JtiGenerator()),
            new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(options.IssuedAt).ToString(), ClaimValueTypes.Integer64),
            new Claim(_options.ClaimsIdentity.UserIdClaimType, user.Id.ToString()),
            new Claim(_options.ClaimsIdentity.UserNameClaimType, user.UserName)
        };
            var userClaims = await userManager.GetClaimsAsync(user);
            var userRoles = await userManager.GetRolesAsync(user);
            claims.AddRange(userClaims);
            //foreach (var userRole in userRoles)
            //{
            //    claims.Add(new Claim(ClaimTypes.Role, userRole));
            //    var role = await roleManager.FindByNameAsync(userRole);
            //    if (role != null)
            //    {
            //        var roleClaims = await roleManager.GetClaimsAsync(role);
            //        foreach (Claim roleClaim in roleClaims)
            //        {
            //            claims.Add(roleClaim);
            //        }
            //    }
            //}
            return claims;
        }

        public async Task<string> GenerateEncodedToken(User user)
        {
            IEnumerable<Claim> claims = await this.GetValidClaims(user);

            var jwt = new JwtSecurityToken(
                issuer: options.Issuer,
                audience: options.Audience,
                claims: claims,
                notBefore: options.NotBefore,
                expires: options.Expiration,
                signingCredentials: options.SigningCredentials);

            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

            return encodedJwt;
        }

【问题讨论】:

  • 这是 JSON Web 令牌吗?
  • @poke 是的,我使用它。

标签: c# asp.net-core jwt asp.net-core-webapi claims-based-identity


【解决方案1】:

在 JSON Web Tokens 中,声明被直接编码为 JWT 有效负载的一部分。 Claim type 具有的附加信息未在 JWT 中编码。

JWT 只关心声明类型和声明值。这些被编码为 JWT 有效负载的直接属性。

所以你的声明应该这样编码:

{
  "sub": "test@test.com",
  "email": "test@test.com",
  "projectname/permission": "engines.manage",
  "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Constructor",
  "iss": "dotnet_TEST",
  "aud": "TEST",
  "nbf": 1534023667,
  "iat": 1534023667,
  "exp": 1534027267
}

【讨论】:

  • 你能提供一些例子如何以这种方式生成令牌吗?
  • 当您创建带有声明列表的JwtSecurityToken 时,您应该在使用JwtSecurityTokenHandler 编写它时自动获得正确的令牌。如果您遇到问题,请显示您当前用于生成令牌的代码。
猜你喜欢
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 2017-07-10
  • 2019-03-10
  • 1970-01-01
  • 2022-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多