Describes the parameter validity verification and permission verification of the ABP framework.

Source: Internet
Author: User

Describes the parameter validity verification and permission verification of the ABP framework.

Parameter validity Verification
The input data of the application should be checked for validity first. The input data can be submitted by users or other applications. In Web applications, two Data Validity tests are usually performed: client and server. The client test mainly enables users to have a good user experience. First, it is best to verify the validity of the form input on the client and the field input displayed to the client is invalid. However, server-side verification is more critical and indispensable (do not perform client-side verification only, but not server-side verification ).

The server side check is usually executed by the Application Service (layer). The method in the Application Service (layer) first checks the data validity before using the verified data. The ABC infrastructure provides a method for automatically verifying the validity of input data.

The Application Service (layer) method obtains a data transmission object (DTO) as the input. An IValidate interface is provided for the ABP interface. DTO can verify the data validity by implementing this interface. Because IInputDto is extended from IValidate, you can directly implement the IInputDto interface to verify the validity of the data transmission object (DTO.

Use Data Annotation
ABP provides data annotation features. Suppose we are developing an application service for task creation and get an input. See the following example:

public class CreateTaskInput : IInputDto{  public int? AssignedPersonId { get; set; }  [Required]  public string Description { get; set; }}

Here, the Description Property is marked as Required. AssignedPersonId is optional. In the System. ComponentModel. DataAnnotations namespace, there are many such features (such as MaxLength, MinLength, and RegularExpression ).

In the System. ComponentModel. DataAnnotations namespace, see the implementation of the Task application service.

 

public class TaskAppService : ITaskAppService{  private readonly ITaskRepository _taskRepository;  private readonly IPersonRepository _personRepository;  public TaskAppService(ITaskRepository taskRepository, IPersonRepository personRepository)  {    _taskRepository = taskRepository;    _personRepository = personRepository;  }  public void CreateTask(CreateTaskInput input)  {    var task = new Task { Description = input.Description };    if (input.AssignedPersonId.HasValue)    {      task.AssignedPerson = _personRepository.Load(input.AssignedPersonId.Value);    }    _taskRepository.Insert(task);  }}


As you can see, no data validation code (verification of the Description attribute) is written here, because ABC will automatically verify the data validity. It also checks whether the input data is null. If it is null, an AbpValidationException is thrown. Therefore, you do not need to write code to check whether the data is null. If the input data with any attribute is invalid, the same exception is thrown.

This mechanism is similar to ASP. net mvc verification. Note: The application service class here is not inherited from the Controller, it is a common class used in Web applications.

Custom check
If the data annotation method cannot meet your needs, you can implement the ICustomValidate interface. See the following example:

public class CreateTaskInput : IInputDto, ICustomValidate{  public int? AssignedPersonId { get; set; }  public bool SendEmailToAssignedPerson { get; set; }  [Required]  public string Description { get; set; }  public void AddValidationErrors(List<ValidationResult> results)  {    if (SendEmailToAssignedPerson && (!AssignedPersonId.HasValue || AssignedPersonId.Value <= 0))    {      results.Add(new ValidationResult("AssignedPersonId must be set if SendEmailToAssignedPerson is true!"));    }  }}

The ICustomValidate interface declares an implemented AddValidationErrors method. Here we have an attribute called SendEmailToAssignedPerson. If this attribute is true, the AssignedPersonId attribute is verified to be valid. Otherwise, the attribute can be empty. If a verification error occurs, you must add the verification results to the result set. (Add ValidationResult to results)

Set the default value
After verifying the data validity, we need to perform an additional operation to sort out the DTO parameters. ABP defines an IShouldNormalize interface, which declares a Normalize method. If you implement this interface, the Normalize method will be called after verifying the data validity. Assume that our DTO needs data in the sorting direction. If this Sorting property is not provided with data, we can set a default value for Sorting in Normalize.

public class GetTasksInput : IInputDto, IShouldNormalize{  public string Sorting { get; set; }  public void Normalize()  {    if (string.IsNullOrWhiteSpace(Sorting))    {      Sorting = "Name ASC";    }  }}


Permission Verification
Almost all enterprise applications have different levels of permission verification. Permission verification is used to check whether a user allows certain specified operations. With the infrastructure, you can perform permission verification.

NOTE: For the IPermissionChecker interface

The Abp permission system uses IPermissionChecker to check authorization. At the same time, you can implement your own method as needed, which has been fully implemented in the module-zero project. If IPermissionChecker is not implemented, NullPermissionChecker is used to grant all permissions to everyone.

Define Permissions
Before using verification permissions, we need to define unique permissions for each operation. The Design of Abp is based on modularity, so different modules can have different permissions. To define permissions, a module should create a derived class of AuthorizationProvider. MyAuthorizationProvider inherits from AuthorizationProvider. In other words, AuthorizationProvider derives MyAuthorizationProvider. Example:

public class MyAuthorizationProvider : AuthorizationProvider{  public override void SetPermissions(IPermissionDefinitionContext context)  {    var administration = context.CreatePermission("Administration");    var userManagement = administration.CreateChildPermission("Administration.UserManagement");    userManagement.CreateChildPermission("Administration.UserManagement.CreateUser");    var roleManagement = administration.CreateChildPermission("Administration.RoleManagement");  }}

IPermissionDefinitionContext has methods to obtain and create permissions.

A permission has the following attributes:

  • Name: the unique Name within the system range. Defining it as a String constant is a good note. We tend to divide "." into different layers, but this is not required. You can set any name you like. The only rule is that the name must be unique.
  • Display Name: Use a localized string to Display permissions to the UI.
  • Description: similar to Display Name.
  • IsGrantedByDefault: whether the permission is granted to (logged-in) All users unless specified. It is usually set to False (default ).
  • MultiTenancySides: for tenant applications, a permission can be based on the tenant or host (Original: host ). This is an enumeration identifier, so the permission can be applied to different aspects (original article: Both Sides ).

A permission can have a parent permission and a sub-permission. Of course, this does not affect the permission check. It only benefits permission classification at the UI Layer. After creating authorizationprovider, we should register it in the module's PreIntialize method. As follows:

Configuration.Authorization.Providers.Add<MyAuthorizationProvider>()

Authorizationprovider is automatically registered to the dependency injection system. Therefore, authorization providers can inject any dependency (such as Repository) to use other resources to create permission definitions.

Check permissions
1. Use the AbpAuthorize feature (Using AbpAuthorize attribute)

AbpAuthorize (AbpMvcAuthorize corresponds to MVC Controllers and AbpApiAuthorize corresponds to Web API Controllers) features are the simplest and most common method to check permissions. Consider the following application service method:

[AbpAuthorize("Administration.UserManagement.CreateUser")]public void CreateUser(CreateUserInput input){  //A user can not execute this method if he is not granted for "Administration.UserManagement.CreateUser" permission.}

Users who do not have the "Administration. UserManagement. CreateUser" permission cannot call CreateUser.

The AbpAuthorize feature also checks whether the current user is logged on (using IAbpSession. UserId ). Therefore, if we declare a method as the AbpAuthorize feature, it will at least check whether the user is logged on. The Code is as follows: [AbpAuthorize]

public void SomeMethod(SomeMethodInput input){  //A user can not execute this method if he did not login.}

2. AbpAuthorize attribute description (AbpAuthorize attribute notes)

You can use a dynamic method to intercept permissions. Therefore, there are some restrictions on using the AbpAuthorize feature. As follows:

Cannot be applied to private methods
Cannot be applied to static methods
It cannot be applied to non-injected classes (we must use dependency injection ).
In addition,

The AbpAuthorize feature can be applied to any Public method. If this method is called by an interface (for example, in Application Services, it is called through an interface)
The method is a virtual method. If this method is directly referenced by a class, it is called (such as ASP. net mvc or Web API Controller ).
The method is virtual (virtual), if this method is protected.
Note: There are three AbpAuthorize features:

(1) In application layer, we use Abp. Authorization. AbpAuthorize;
(2) In the MVC controller (web layer), we use Abp. Web. Mvc. Authorization. AbpMvcAuthorize;
(3) In ASP. NET Web API, we use Abp. WebApi. Authorization. AbpApiAuthorize.
These three classes are inherited from different places.

In MVC, It inherits from the MVC Authorize class.
In a Web API, It inherits from the Authorize class of the Web API. Therefore, it is best to inherit from MVC and Web APIs.
However, at the Application layer, it is completely implemented by the Abp itself without any extension sub-classes.
3. Use IPermissionChecker

AbpAuthorize applies in most cases, but in some cases, we still need to perform permission verification on our own in the method body. We can inject and use IPermissionChecker objects. Code for the following edge:

 public void CreateUser(CreateOrUpdateUserInput input){  if (!PermissionChecker.IsGranted("Administration.UserManagement.CreateUser"))  {    throw new AbpAuthorizationException("You are not authorized to create user!");  }  //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission.}

Of course, you can write any logic, because the IsGranted method simply returns true or false (it also has an asynchronous version ). If you simply check a permission and throw an exception like the code above, you can use the Authorize method:

public void CreateUser(CreateOrUpdateUserInput input){  PermissionChecker.Authorize("Administration.UserManagement.CreateUser");  //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission.}

Because permission verification is usually implemented with the Application layer, the ApplicationService basic class injects and defines the PermissionChecker attribute. Therefore, the permission checker allows you to use it in the Application Service class without displaying injection.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.