When you’ve built a user system, at some point your API needs to determine whether the currently accessing user can access the current resource. This is where you need to build your own permissions system. Authorization is a very important concept in the permission system. Authorization refers to the process of judging what permissions users have, and authentication is two completely different meanings.

Currently widely used two kinds of competence model as: role-based access control (RBAC) and attribute-based access control (ABAC), each have advantages and disadvantages between them: RBAC model to build up more simple, the disadvantage is can’t to resource fine-grained authorization (is one kind of resource, not authorized a certain specific resources); ABAC model construction is relatively complex, high learning cost, the advantages of fine granularity and dynamic execution according to context.

In Authing’s authority system, we implement RBAC model role authority inheritance through user and role objects, and on top of that, we can implement ABAC authority model through dynamic and fine-grained authorization around attributes. At the same time, in order to meet the design requirements of complex organizational architecture in large systems, resources, roles and permissions are unified into one permission group:

With Authing’s powerful and flexible permissions system, you can quickly build a permissions model to suit your business scenario. Let’s take a simple scenario from the real world as an example.

Introduction to permission Model

What is Role-based Access Control (RBAC)

Role-based Access Control (RBAC) refers to granting related permissions to users through their roles. To put it simply, it is more flexible, efficient and extensible than granting permissions directly to users.

When RBAC is used, system users are assigned different roles based on common responsibilities and requirements by analyzing their actual situation. You can grant users one or more roles, each of which has one or more permissions. This user-role, role-permission relationship allows us to no longer manage individual users individually, but users inherit permissions from the granted roles.

In a simple scenario (Gitlab permission system), the user system has Admin, Maintainer, and Operator roles. These roles have different permissions. For example, only Admin has permissions to create and delete code repositories.

We grant a user the role of “Admin” and he has the “create repository” and “delete repository” permissions.

For future scalability, users are not directly authorized with policies. For example, if multiple users have the same permission, you need to assign the same permission to each user and modify the permission for each user. After a role is created, you only need to set permissions for the role and assign different roles to different users. You only need to modify the permissions of the role to automatically change the permissions of all users in the role.

What is Attribute Based Access Control (ABAC)

Attribute-based Access Control (ABAC) is a flexible authorization model, which controls the Access to objects through one or a group of attributes. ABAC attributes are generally divided into four categories: user attributes (such as user age), environment attributes (such as current time), operation attributes (such as read) and object attributes (such as an article, also known as resource attributes), so in theory it can achieve very flexible permission control:

Under the ABAC permission model, you can easily implement the following permission control logic:

  1. Authorized editing A The editing permission of A specific book;
  2. When the department of a document is the same as the user’s department, the user can access the document.
  3. When the user is the owner of a document and the status of the document is draft, the user can edit the document.
  4. Block access to System B from Department A until 9:00 a.m.
  5. Access to system A as an administrator is prohibited in places other than Shanghai;

There are several commonalities in the above logic:

  1. Specific to one resource rather than one type of resource;
  2. Specific to an operation;
  3. Dynamic execution of policies based on the context of the request (such as time, location, resource Tag);

If boiled down to a single sentence, you can fine-grained grant specific permissions to a resource under what circumstances.

Introduction to Authorization Mode

Authing supports two licensing modes:

  1. Through the authorization code pattern based on OAuth 2.0 process. 1.
  2. Manage user authorization through permission API.

Implement the permission model with Authing

Let’s take the pattern of calling the permissions API as an example.

Create the role

You can create roles using the Authing console: Under Permissions Management – Role Management, click the Add Role button:

  • Role code: unique identifier of the role. This identifier can contain only letters, digits, underscores (_), and hyphens (-).
  • Role Description: Specifies the description of the role. Set this parameter to administrator.

Create three roles:

You can also create roles using the API & SDK, see The Role Management SDK for details. 2.

Authorized User Role

On the role details page, you can authorize this role to the user. You can search users by username, mobile phone number, email, nickname:

After selecting the user and clicking OK, you can view a list of users who are authorized to play the role.

You can also use the API & SDK to grant roles to users, see the Role Management SDK for details. 2.

The back-end controls permissions through user roles

After the user has successfully authenticated and obtained the Token, you can resolve to the ID of the current user. Then you can use the API & SDK provided by us to obtain the role granted to the user at the back end. Here we take Node.js as an example:

Start by getting a list of all the roles the user has been granted:

import { ManagementClient } from 'authing-js-sdk'

const managementClient = new ManagementClient({
  userPoolId: 'YOUR_USERPOOL_ID',
  secret: 'YOUR_USERPOOL_SECRET',
})
const { totalCount, list } = await managementClient.users.listRoles('USER_ID')
Copy the code

Once we have all of the user’s roles, we can determine if the user has the role of Devops:

if (! List.map ((role) => role.code).includes('devops')) {throw new Error(' no permissions! ')}Copy the code

Create a resource

In the previous step, we control permissions by whether the user has a certain role. This kind of permission control is coarse-grained, because we only judge whether the user has a certain role, but not whether the user has a specific permission. Authing is also capable of more fine-grained authorization around resources, based on the role-based access control model (RBAC).

You can abstract objects of the system as resources on which operations can be defined. For example, in this scenario, Repository, Tag, PR, and Release Notes are all resources with corresponding operations:

  1. Repository: create, delete, etc.
  2. PR: open, comment, merge, etc.
  3. Tag: create, delete, etc.
  4. Release Notes: Create, read, edit, delete, etc.

We created these resources in Authing:

Authorization Permission of a role to operate resources

Authing also supports granting permissions to users and roles, and if a user is in a role, he inherits the permissions granted to that role. As a result, Authing is able to implement both the standard RBAC permission model and more fine-grained and dynamic permission control on top of it. In this example, we grant Create and Delete permissions to the admin role for the repository resource:

The backend determines whether the user has permissions

In the previous step, we authorized a user (role) to operate a specific resource through resource authorization. In the back-end interface authentication, we can make more fine-grained judgments:

Initialize the Management SDK first:

Here is the Node SDK as an example, we also support Python, Java, C#, PHP and other languages SDK, please click here. 3.

import { ManagementClient } from 'authing-js-sdk'

const managementClient = new ManagementClient({
  userPoolId: 'YOUR_USERPOOL_ID',
  secret: 'YOUR_USERPOOL_SECRET',
})
Copy the code

Call managementClient. Acl. IsAllowed method, the parameters are:

  • UserId: indicates the userId. A user can be directly authorized to perform operations on specific resources or inherit the permissions granted to roles.
  • Resource: indicates a resource identifier. For example, repository:123 indicates a code repository whose ID is 123. R repository:* indicates a code repository.
  • Action: indicates a specific operation, such as repository:Delete indicates the operation to Delete the code repository.
  • Options: Other options are optional
    • Options. namespace: indicates the resource owning permission group code

const { totalCount, list } = await managementClient.acl.isAllowed(
  'USER_ID',
  'repository:123',
  'repository:Delete'
)
Copy the code

The Authing policy engine will dynamically execute the policy based on the configured permission policy and return true or false. You can determine whether the user has the operation permission based on the return value.

conclusion

This article started with the simplest RBAC permission model and then went on to show you how to do a more fine-grained, dynamic ABAC permission model, and the process was gradual, as you moved to the ABAC permission model as the complexity of your business grew.

Jump link:

1. The docs. Authing. Cn/v2 / concepts… 2. The docs. Authing. Cn/v2 / referenc… 3. The docs. Authing. Cn/v2 / referenc…


If you like our content, welcome to pay attention to the public account “Authing identity cloud” and visit our blog Authing blog, more interesting content waiting for you to see ~