mirror of https://github.com/abpframework/abp.git
4 changed files with 238 additions and 2 deletions
@ -1,3 +1,239 @@ |
|||
## Authorization |
|||
# Authorization |
|||
|
|||
TODO |
|||
Authorization is used to check if a user is allowed to perform some specific operation in the application. |
|||
|
|||
ABP extends [ASP.NET Core's Authorization system](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/introduction) by adding **permissions** as auto [policies](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies) and allowing authorization system to be usable in the **[application services](Application-Services.md)** too. |
|||
|
|||
So, all the ASP.NET Core authorization features and the documentation are valid in an ABP based application. This document focuses on the features added on top of them. |
|||
|
|||
## Authorize Attribute |
|||
|
|||
ASP.NET Core defines the [**Authorize**](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/simple) attribute that can be used for an action, a controller or a page. ABP allows you to use the same attribute for an [application service](Application-Services.md) too. |
|||
|
|||
Example: |
|||
|
|||
````csharp |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace Acme.BookStore |
|||
{ |
|||
[Authorize] |
|||
public class AuthorAppService : ApplicationService, IAuthorAppService |
|||
{ |
|||
public Task<List<AuthorDto>> GetListAsync() |
|||
{ |
|||
... |
|||
} |
|||
|
|||
[AllowAnonymous] |
|||
public Task<AuthorDto> GetAsync(Guid id) |
|||
{ |
|||
... |
|||
} |
|||
|
|||
[Authorize("BookStore_Author_Create")] |
|||
public Task CreateAsync(CreateAuthorDto input) |
|||
{ |
|||
... |
|||
} |
|||
} |
|||
} |
|||
|
|||
```` |
|||
|
|||
* `Authorize` attribute forces user to login to the application in order to use the `AuthorAppService` methods. So, `GetListAsync` method is only available to authenticated users. |
|||
* `AllowAnonymous` suppress the authentication. So, `GetAsync` method is available to everyone including unauthorized users. |
|||
* `[Authorize("BookStore_Author_Create")]` defines a policy (see [policy based authorization](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies)) that is checked to authorize the current user. |
|||
|
|||
"BookStore_Author_Create" is an arbitrary policy name. If you declare an attribute like that, ASP.NET Core authorization system expects a policy defined before. |
|||
|
|||
You can of course implement your policies as stated in the ASP.NET Core documentation. But for simple true/false cases (that means a policy was granted a user or not), ABP defines the permission system explained in the next section. |
|||
|
|||
## Permission System |
|||
|
|||
A permission is a simple policy where it is granted or prohibited for a particular user, role or client. |
|||
|
|||
### Defining Permissions |
|||
|
|||
To define permissions, create a class inheriting from the `PermissionDefinitionProvider` as shown below: |
|||
|
|||
````csharp |
|||
using Volo.Abp.Authorization.Permissions; |
|||
|
|||
namespace Acme.BookStore.Permissions |
|||
{ |
|||
public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var myGroup = context.AddGroup("BookStore"); |
|||
|
|||
myGroup.AddPermission("BookStore_Author_Create"); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
> ABP will automatically discover this class. No additional configuration required. |
|||
|
|||
In the `Define` method, you first need to add a **permission group** (or get an existing group) then add **permissions** to this group. |
|||
|
|||
When you define a permission, it becomes usable in the ASP.NET Core authorization system as a **policy** name. It also becomes visible in the UI. See permissions dialog for a role: |
|||
|
|||
 |
|||
|
|||
* The "BookStore" group is shown as a new tab on the left side. |
|||
* "BookStore_Author_Create" on the right side is the permission name. You can grant or prohibit it for the role. |
|||
|
|||
When you save the dialog, it is saved to the database and used in the authorization system. |
|||
|
|||
> The screen above is available when you have installed the identity module, which is basically used for user and role management. Startup templates come with the identity module pre-installed. |
|||
|
|||
#### Localizing the Permission Name |
|||
|
|||
"BookStore_Author_Create" is not a good permission name on the UI. Fortunately, `AddPermission` and `AddGroup` methods can take `LocalizableString` as second parameters: |
|||
|
|||
````csharp |
|||
var myGroup = context.AddGroup( |
|||
"BookStore", |
|||
LocalizableString.Create<BookStoreResource>("BookStore") |
|||
); |
|||
|
|||
myGroup.AddPermission( |
|||
"BookStore_Author_Create", |
|||
LocalizableString.Create<BookStoreResource>("Permission:BookStore_Author_Create") |
|||
); |
|||
```` |
|||
|
|||
Then you can define texts for "BookStore" and "Permission:BookStore_Author_Create" keys in the localization file: |
|||
|
|||
````json |
|||
"BookStore": "Book Store", |
|||
"Permission:BookStore_Author_Create": "Creating a new author" |
|||
```` |
|||
|
|||
> See the [localization document](Localization.md) for more details on the localization system. |
|||
|
|||
The localized UI will be like that: |
|||
|
|||
 |
|||
|
|||
#### Multi-Tenancy |
|||
|
|||
ABP supports [multi-tenancy](Multi-Tenancy.md) as a first class citizen. You can define multi-tenancy side option while defining a new permission. It gets one of the three values defined below: |
|||
|
|||
* **Host**: The permission is available only for the host side. |
|||
* **Tenant**: The permission is available only for the tenant side. |
|||
* **Both** (default): The permission is available both for tenant and host sides. |
|||
|
|||
> If your application is not multi-tenant, you can ignore this option. |
|||
|
|||
To set the multi-tenancy side option, pass to the third parameter of the `AddPermission` method: |
|||
|
|||
````csharp |
|||
myGroup.AddPermission( |
|||
"BookStore_Author_Create", |
|||
LocalizableString.Create<BookStoreResource>("Permission:BookStore_Author_Create"), |
|||
multiTenancySide: MultiTenancySides.Tenant //set multi-tenancy side! |
|||
); |
|||
```` |
|||
|
|||
#### Child Permissions |
|||
|
|||
A permission may have child permissions. It is especially useful when you want to create a hierarchical permission tree where a permission may have additional sub permissions which are available only if the parent permission has been granted. |
|||
|
|||
Example definition: |
|||
|
|||
````csharp |
|||
var authorManagement = myGroup.AddPermission("Author_Management"); |
|||
authorManagement.AddChild("Author_Management_Create_Books"); |
|||
authorManagement.AddChild("Author_Management_Edit_Books"); |
|||
authorManagement.AddChild("Author_Management_Delete_Books"); |
|||
```` |
|||
|
|||
The result on the UI is shown below (you probably want to localize permissions for your application): |
|||
|
|||
 |
|||
|
|||
For the example code, it is assumed that a role/user with "Author_Management" permission granted may have additional permissions. Then a typical application service that checks permissions can be defined as shown below: |
|||
|
|||
````csharp |
|||
[Authorize("Author_Management")] |
|||
public class AuthorAppService : ApplicationService, IAuthorAppService |
|||
{ |
|||
public Task<List<AuthorDto>> GetListAsync() |
|||
{ |
|||
... |
|||
} |
|||
|
|||
public Task<AuthorDto> GetAsync(Guid id) |
|||
{ |
|||
... |
|||
} |
|||
|
|||
[Authorize("Author_Management_Create_Books")] |
|||
public Task CreateAsync(CreateAuthorDto input) |
|||
{ |
|||
... |
|||
} |
|||
|
|||
[Authorize("Author_Management_Edit_Books")] |
|||
public Task UpdateAsync(CreateAuthorDto input) |
|||
{ |
|||
... |
|||
} |
|||
|
|||
[Authorize("Author_Management_Delete_Books")] |
|||
public Task DeleteAsync(CreateAuthorDto input) |
|||
{ |
|||
... |
|||
} |
|||
} |
|||
```` |
|||
|
|||
* `GetListAsync` and `GetAsync` will be available to users if they have `Author_Management` permission granted. |
|||
* Other methods require additional permissions. |
|||
|
|||
## IAuthorizationService |
|||
|
|||
ASP.NET Core provides the `IAuthorizationService` that can be used to check for authorization. Once you inject, you can use it in your code to conditionally control the authorization. |
|||
|
|||
Example: |
|||
|
|||
````csharp |
|||
public async Task CreateAsync(CreateAuthorDto input) |
|||
{ |
|||
var result = await AuthorizationService |
|||
.AuthorizeAsync("Author_Management_Create_Books"); |
|||
if (result.Succeeded == false) |
|||
{ |
|||
//throw exception |
|||
throw new AbpAuthorizationException("..."); |
|||
} |
|||
|
|||
//continue to the normal flow... |
|||
} |
|||
```` |
|||
|
|||
> `AuthorizationService` is available as a property when you derive from ABP's `ApplicationService` base class. Since it is widely used in application services, `ApplicationService` pre-injects it for you. Otherwise, you can directly [inject](Dependency-Injection.md) it into your class. |
|||
|
|||
Since this is a typical code block, ABP provides extension methods to simplify it. |
|||
|
|||
Example: |
|||
|
|||
````csharp |
|||
public async Task CreateAsync(CreateAuthorDto input) |
|||
{ |
|||
await AuthorizationService.CheckAsync("Author_Management_Create_Books"); |
|||
|
|||
//continue to the normal flow... |
|||
} |
|||
```` |
|||
|
|||
`CheckAsync` extension method throws `AbpAuthorizationException` if current user/client has not granted for the given permission. There is also `IsGrantedAsync` extension method that returns `true` or `false`. |
|||
|
|||
> Tip: Prefer to use the `Authorize` attribute wherever possible, since it is declarative & simple. Use `IAuthorizationService` if you need to conditionally check a permission and run a business code based on the permission check. |
|||
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 42 KiB |
Loading…
Reference in new issue