Detailed ABP framework parameter validation and permission validation _ Basic Application

Source: Internet
Author: User

Validation of parameter Validation
The input data for an application should first be checked for validity. The data entered can be submitted by a user or other application. In Web applications, 2 data validation tests are typically performed: client-side and server-end testing. The main test of the client is to make the user have a good user experience. First, it is best to verify the validity of its form input on the client and the field input that is displayed to the client is invalid. However, server-side checksums are more critical and indispensable (do not just do client-side validation without server-end validation).

Server-side testing is usually performed by the application Service (layer), and the methods in the Application service (layer) first verify the validity of the data before using the validated data. The ABP infrastructure provides a way to automatically verify the validity of input data.

The Application Service (layer) method obtains a data transfer object (DTO) as input. ABP has a ivalidate interface that the DTO can use to verify the validity of the data by implementing the interface. Because the iinputdto extends from ivalidate, you can directly implement the Iinputdto interface to test the validity of the data transfer object (DTO).

Using data annotations
ABP provides attributes of data annotations. Suppose we are developing an application service to create a task 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. There are many such features in the System.ComponentModel.DataAnnotations namespace (for example, MaxLength, MinLength, RegularExpression, and so on).

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, there is no data validation code written here (which means validation of the Description property) because ABP automatically verifies the validity of the data. ABP also verifies that the input data is null. If empty, the Abpvalidationexception exception is thrown. So you don't need to write code that checks whether the data is null. It also throws the same exception if the input data for any property is invalid.

This mechanism is similar to the validation of ASP.net MVC, noting that the application service class here is not inherited from controller, which is a generic class used in Web applications.

Custom validation
If the data annotation method does not meet your needs, you can implement the Icustomvalidate interface, please 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 are true!"));
    }



The Icustomvalidate interface declares a addvalidationerrors method that can be implemented. Here we have a property called Sendemailtoassignedperson. If the property is true, the Assignedpersonid property is checked for validity, otherwise the property can be empty. If there are validation errors, we must add these validation results to the result collection. (just add validationresult to results)

Set default values
after verifying the validity of the data, we need to perform an additional operation to collate the DTO parameters. ABP defines a ishouldnormalize interface that declares a normalize method. If you implement this interface, the normalize method will be invoked after verifying the validity of the data. Suppose our dto needs a sort direction of data. If this sorting attribute is not provided, then in normalize we can set a default value for sorting.

public class Gettasksinput:iinputdto, ishouldnormalize
{public
  string sorting {get; set;}

  public void normalize ()
  {
    if (string). Isnullorwhitespace (sorting))
    {
      sorting = ' Name ASC ';
    }
}}


Permission Validation
Almost all enterprise-class applications have different levels of permission validation. Permission validation is used to check whether a user allows certain actions to be specified. ABP has the infrastructure to allow you to implement permission validation.

Note: About the Ipermissionchecker interface

The ABP permission system uses Ipermissionchecker to check authorization. At the same time you can implement your own way according to your needs, which has been fully implemented in the Module-zero project. If Ipermissionchecker is not implemented, Nullpermissionchecker will be used to authorize all permissions to everyone.

Defining permissions
before using authentication 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. In order to define permissions, a module should create Authorizationprovider derived classes. Myauthorizationprovider inherits from Authorizationprovider, in other words authorizationprovider derives myauthorizationprovider. Examples are as follows:

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 a way to get and create permissions.

A permission has the following properties:

    • Name: System-wide unique name. It's a good idea to define it as a string constant. We tend to be "." Split different levels, but that's not required. You can set any name you like. The only rule is that the name must be unique.
    • Display Name: Displays permissions to the UI using a localized string.
    • Description: Similar to display name.
    • Isgrantedbydefault: This permission is granted to (logged in) all users unless the display is specified. This is usually set to False (the default value).
    • Multitenancysides: For tenant applications, a permission can be based on tenant or host (original: host). This is an enumeration identity, so permissions can be applied to different aspects (original: Both Sides).

A permission can have both parent and child permissions. Of course, this does not affect permission checking, it is only good for permission collations at the UI layer. After creating the Authorizationprovider, we should register it in the Preintialize method of the module. As follows:

Configuration.authorization.providers.add<myauthorizationprovider> ()

Authorizationprovider is automatically registered in the dependency injection system. Therefore, authorization provider can inject any dependency (like repository) to use other resources to create a permission definition.

Check Permissions
1. Use abpauthorize characteristics (using Abpauthorize attribute)

Abpauthorize (abpmvcauthorize corresponds to the MVC controllers and abpapiauthorize corresponding WEB API controllers) feature is the simplest and most common way to check permissions. Please consider the following application service method:

[Abpauthorize ("Administration.UserManagement.CreateUser")]
public void CreateUser (Createuserinput input)
{
  //a user can don't execute this method if it isn't granted for "ADM Inistration. Usermanagement.createuser "permission.
}

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

The Abpauthorize feature also checks whether the current user is logged on (using Iabpsession.userid). Therefore, if we declare a method as a abpauthorize attribute, it will at least check that the user is logged in. The code is as follows: [Abpauthorize]

public void SomeMethod (Somemethodinput input)
{
  //a user can don't execute this method if him did not login.
}

2.AbpAuthorize attribute notes (abpauthorize attribute notes)

ABP uses dynamic methods to intercept for permission validation. Therefore, there are some limitations to the method of using the Abpauthorize attribute. As follows:

cannot be applied to private methods
cannot be applied to static methods
cannot be applied to non-injection (non-injected) classes (we must use dependency injection).
Furthermore

The Abpauthorize attribute can be applied to any public method if this method is invoked by an interface (for example, in application services through an interface)
Method is virtual (virtual) If this method is directly invoked by a class reference (such as a asp.net MVC or a controller of the Web API).
Method is virtual (virtual), if this method is protected.
Note: There are three kinds of abpauthorize features:

(1) In the Application service (application layer), we use Abp.Authorization.AbpAuthorize;
(2) in the MVC controller (Web layer), we use Abp.Web.Mvc.Authorization.AbpMvcAuthorize;
(3) in the ASP.net Web API, we use Abp.WebApi.Authorization.AbpApiAuthorize.
These three classes inherit from different places.

In MVC, it inherits from MVC's own authorize class.
In the Web API, it inherits from the authorize class of the Web API. Therefore, it is best to inherit into MVC and the Web API.
However, at the application layer, it is entirely implemented by ABP itself without any extension of the subclass of any class.
3. Use of Ipermissionchecker

Abpauthorize applies to most situations, but in some cases we still need to validate the permissions in the method body. We can inject and use Ipermissionchecker objects. As shown in the code below:

 public void CreateUser (Createorupdateuserinput input)
{
  if (! Permissionchecker.isgranted ("Administration.UserManagement.CreateUser"))
  {
    throw new Abpauthorizationexception ("You are don't authorized to create user!");
  }

  A user can not reach this point if it isn't 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 of OH). If you simply check a permission and throw an exception like the top code, you can use the authorize method:

public void CreateUser (Createorupdateuserinput input)
{
  permissionchecker.authorize (" Administration.UserManagement.CreateUser ");

  A user can not reach this point if it isn't granted for "Administration.UserManagement.CreateUser" permission.
}

Because permission validation is typically implemented with the application layer, the Applicationservice base class injects and defines the PermissionChecker attribute. Therefore, the Permission Checker allows you to use the Application service class without having to display the injection.

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.