Based on. Netcore3.1 series — the initial knowledge of authentication and authorization scheme

Time:2020-11-15

1. Preface

reviewJwtbearer authentication in authentication authorization scheme

授权

In the last article, we used jwtbearer authentication method to understand that the authentication is based on claims. Therefore, we can obtain the user‘s claims through the user token, and verify these claims in the authorization process, so as to determine whether we have the permission to obtain or perform the target resource operation. This chapter will introduce ASP.NET Simple use of core’s authorization system.

2. Description

Authorization and authentication are independent of each other, but authorization requires an authentication mechanism. Therefore, authentication can create one or more identities for the current user, which is the process of determining the user’s real identity. Authorization is a process to determine the actions that users can perform according to their identities. The essence of authorization is that users with certain characteristics have the right to access a resource or perform an operation. For example, a user with administrator status has the operation rights of creating personnel, deleting personnel, editing personnel and deleting personnel, while a non administrative user has only the right to read his own information.

At this point, you may ask, what features of a user can be authorized to access a resource or perform an operation. From this, we introduce the way of authorization strategy, which can be authorized according to the user’s role, position, department or even gender, age and other characteristics of the user.

By establishing authorization policy, the identity statement (claims principal object) carried by the authenticated user is verified to be consistent with the authorization policy, so as to determine whether the user can perform the operation.

授权

3. Authorization

3.1. Role based

3.1.1 adding roles

Assign a role to a controller or an operation within a controller, specifying that the current user must be its role to access the requested resource.

have access toAuthorizeThe roles attribute of the requested resource specifies the role of the requested resource.

For example:

  • The “admin” role is assigned to users for access operations
[Authorize(Roles ="admin")]
public class WeatherForecastController : ControllerBase
{

}
  • Separate role names with commas to allow multiple role access operations
[Authorize(Roles ="admin,user")]
public class WeatherForecastController : ControllerBase
{ 


}

As long as it is satisfiedadmminperhapsuserOne is to visit.

  • At the same time, the access operation of multiple roles specified is satisfied
[Authorize(Roles = "admin")]
[Authorize(Roles = "user")]
public class WeatherForecastController : ControllerBase
{ 
}

3.1.2 add policy role

You can create a policy for access control, and add a registration authorization service policy in the configuration authorization service.

stay Startup.cs In the document, through theConfigureServices()Configure the service to create aadminOnly users in the role can access the policy

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        //Add authorization role policy
        services.AddAuthorization(options =>
        {
            options.AddPolicy("BaseRole", options => options.RequireRole("admin"));
        });
        //Or specify multiple allowed roles
        //services.AddAuthorization(options =>
        // {
        //    options.AddPolicy("MoreBaseRole", options => options.RequireRole("admin","user"));
        // });
    }

Use characteristics in controller methodPolicyTo apply the policy

[Authorize(Policy = "BaseRole")]
    public class WeatherForecastController : ControllerBase
    {
    
    }

3.2. Based on declaration

3.2.1 add statement

The statement that the current user must own and assign the claim to a controller or operation within the controller. Therefore, the specified declaration must hold the corresponding value in order to access the request resource.

Claims are based on policies, so you must build a policy that represents the claim requirements before you can authorize.

The simplest type declaration is to determine whether the declaration exists without checking the value.

You can create a policy for access control, and add a registration authorization service policy in the configuration authorization service.

stay Startup.cs In the document, through theConfigureServices()Configure the service to create a policy that allows users with claims access

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        //Add claims based authorization
        services.AddAuthorization(options =>
        {
            options.AddPolicy("BaseClaims", options => options.RequireClaim("name"));
        });
    }

BaseClaimsThe claim policy will be checkednameWhether there is a claim for the current identity.

Use characteristics in controller methodPolicyTo apply the policy

[Authorize(Policy = "BaseClaims")]
    public class WeatherForecastController : ControllerBase
    {
    
    }

However, most of the time, we need to declare that it contains values. Only by specifying a list of allowed values can authorization succeed. Therefore, you can add the specified value.

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        //Add a claim based authorization to specify a list of allowed values.
        services.AddAuthorization(options =>
        {
            options.AddPolicy("BaseClaims", options => options.RequireClaim("name","i3yuan"));
        });
    }

3.3 strategy based

Both role-based and claim based authorization described above use requirements, request handlers, and preconfigured policies. These provide convenience in building, but ultimately, authorization policies are generated. ASP.NET Core, designed another flexible authorization method, a richer reusable authorization structure, policy based authorization, which is also the core of authorization.

This section will first talk about the application of authorization policy, and in the next section, the core of authorization policy will be explained step by step.

Above, we briefly introduced the role authorization based on policy, but this method is no more than role-based or declaration.

Therefore, we implement authorization based on custom policy authorization.

To customize authorization, we need to write our own policy provider, generate different policies according to different parameters, and re implement the policy. Policy requirements consist of two elements: a requirement class that preserves only data, and an authorization handler that authenticates the data to the user. Create custom requirements and further express specific policies.

3.3.1. Define permission policyPermissionRequirement

Define a permission policy that contains some properties.

public class PermissionRequirement: IAuthorizationRequirement
{
    public string _permissionName { get; }

    public PermissionRequirement(string PermissionName)
    {
        _permissionName = PermissionName;
    }
}

3.3.2. Define a policy processing class again

public class PermissionRequirementHandler : AuthorizationHandler
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
    {
        var role = context.User.FindFirst(c => c.Type == ClaimTypes.Role);
        if (role != null)
        {
            var roleValue = role.Value;
            if (roleValue==requirement._permissionName)
            {
                context.Succeed(requirement);
            }
        }
        return Task.CompletedTask;

The authorization handler reads the claims associated with the role user and checks the custom roles. If the roles match, the success is achieved. Otherwise, the success cannot be returned.

The user-defined declaration here is fixed, but you can also run queries through the database or external services to obtain the judgment conditions corresponding to the user's relevant role information, so as to judge and process in the processor.

Authorization handler calls methodSucceed, and the current request is passed to notify that the request has been successfully validated. If there is no pass request, the handler does not need to do anything and can return the content directly. However, if the handler is to determine if the requirement is not met (regardless of whether the other handler has successfully verified the same requirement), the method is called on the authorization context objectFail

3.3.3. The following shows how to add custom requirements to the policy

(note that since this is a custom requirement, there is no extension method, and you must continue processing the entire policy objectRequirementsCollection:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        //Authorization based on custom policy
        services.AddAuthorization(options =>
        {
            options.AddPolicy("customizePermisson",
              policy => policy
                .Requirements
                .Add(new PermissionRequirement("admin")));
        });
        //In addition, a new handler needs to be registered with the di system within the scope of the iauthorizationhandler type:
        services.AddScoped();
        //As mentioned earlier, the requirement can contain multiple handlers. If more than one handler is registered with the di system for the same request of the authorization layer, one success is sufficient.

    }

3.3.4. Features of applying custom policies

Specifies that the current user must be an application to the controller or an operation within the controller, such as

[Authorize(Policy = "customizePermisson")]
    public class WeatherForecastController : ControllerBase
    { 
    }

4. Scene

In the jwtbearer authentication of the last authentication and authorization scheme, we have implemented the way to obtain the token. This time, we implement an authentication and authorization based on the role scenario.

In the original token generation method, add one more claim that declares the role, as follows:

new Claim(JwtClaimTypes.Role,”admin”)

[HttpGet]
    public IActionResult GetToken()
    {
        try
        {
            //Define issuer
            string iss = "JWTBearer.Auth";
            //Audience definition
            string aud = "api.auth";
            //Many kinds of claims are defined, such as claims, information storage parts, and the entities of claims generally contain users and some metadata
            IEnumerable claims = new Claim[]
            {
                new Claim(JwtClaimTypes.Id,"1"),
                new Claim(JwtClaimTypes.Name,"i3yuan"),
                new Claim(JwtClaimTypes.Role,"admin"),
            };
            //Notbefore effective time
            // long nbf =new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds();
            var nbf = DateTime.UtcNow;
            //Expires // expiration time
            // long Exp = new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds();
            var Exp = DateTime.UtcNow.AddSeconds(1000);
            //Signingcredentials
            String sign = "q2xiarx $4x3tkqbj"; // the length of SecurityKey must be greater than or equal to 16 characters
            var secret = Encoding.UTF8.GetBytes(sign);
            var key = new SymmetricSecurityKey(secret);
            var signcreds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            //String issuer = default(String), String audience = default(String), IEnumerable claims = null, Nullable notBefore = default(Nullable), Nullable expires = default(Nullable), SigningCredentials signingCredentials = null
            var jwt = new JwtSecurityToken(issuer: iss, audience: aud, claims:claims,notBefore:nbf,expires:Exp, signingCredentials: signcreds);
            var JwtHander = new JwtSecurityTokenHandler();
            var token = JwtHander.WriteToken(jwt);
            return Ok(new
            {
                access_token = token,
                token_type = "Bearer",
            });
        }
        catch (Exception ex)
        {
            throw;
        }
    }

For a controller or an operation within a controller, specify that the current user must be its role to access the requested resource, such asWeatherForecastController.cs

[ApiController]
[Route("[controller]")]
[Authorize(Roles ="admin")]
public class WeatherForecastController : ControllerBase
{ 
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger _logger;

    public WeatherForecastController(ILogger logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IEnumerable Get()
    {
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

5. Operation

5.1. Get token

Obtain the token issued when the role is admin and role is user. Only when the role is admin can the token be authorized.

5.2. Authorization of resource interface access

If the role is admin

授权

授权

When the role is user

授权

授权

It can be seen from the above that only when the role is admin can the target resource be accessed for operation.

6. Summary

  1. From the authentication of the previous article to the authorization phase of this article, a brief introduction is given Asp.net Core’s authentication and authorization system has a preliminary understanding and use of authorization. Authorization can be divided into two types: one is role-based authorization, but with the increase of roles, it will restrict the processing of authorization, which is not suitable for expressing complex authorization logic. The other is policy based authentication, which consists of a series of claims based requirements and a set ofHTTPCustom logic for any other information injected by context or external sources. Each of these requirements is associated with one or more processors that are responsible for the actual calculation of the requirements.
  2. You can see that, asp.net The authorization policy provided by core is a very powerful, rich and flexible authentication and authorization scheme, which can meet most authorization scenarios.
  3. If there is something wrong or incomprehensible, I hope you can point out more, ask questions, discuss together, keep learning and make progress together.
  4. Therefore, in the following chapters, we will continue to explore the authorization system and explain the core of the authorization strategy step by step.
  5. This example source code address

References

Recommended Today

Regular expression sharing for checking primes

This regular expression is shown as follows: Regular expressions for checking prime numbers or not To use this positive regular expression, you need to convert the natural number into multiple 1 strings. For example, 2 should be written as “11”, 3 should be written as “111”, 17 should be written as “11111111111”. This kind of […]