简体   繁体   中英

Check user claims during request in ASP .NET Core Web API

I have defined policies in 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);
    });
});

Permissions class:

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

Later I implemented endpoint in controller with defined policy.

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

I test via postman using Bearer token to check access to this endpoint. Tested user had policy PolicyTypes.Engines.Manage . Result of decoded token.

{
  "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
}

When I execute request I get code 200 and result json form endpoint. What can be the reason that I don't get 403 forbidden?

I present code to generate token.

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;
        }

In JSON Web Tokens, claims are encoded directly as part of the JWT payload. The additional information that the Claim type has are not encoded in JWT.

All that JWT cares about is the claim type, and the claim value. And those are encoded as direct properties of the JWT payload.

So your claims should be encoded like this:

{
  "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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM