Authorization (RBAC/Data Permissions)
10/30/24About 1 min
RBAC Permission System
In our application, verifying who the user is (Authentication) is not enough — we also need to determine what the user is allowed to do (Authorization). This is implemented through a classic Role-Based Access Control (RBAC) system.
Core Concept: User -> Role -> Permission
- Permission: The smallest authorization unit, defined as permission to access a specific API endpoint
- Role: A collection of permissions. E.g., "Admin" role has full CRUD on user management; "Guest" role has read-only access
- User: Each user is assigned one or more roles. The user's total permissions are the union of all their roles' permissions
Workflow: From Request to Authorization Decision
Step 1: AuthMid - Build Request Context (ReqCtx)
- Parses the HTTP request (method, path, query params)
- Normalizes the path (removes /api prefix)
- Builds a structured
ReqCtxobject - Injects
ReqCtxinto request extensions
Step 2: ApiMid - Permission Verification
- Gets
ReqCtx(what is being requested) andUserInfo(who is requesting) from request extensions - Calls the core permission check function
check_api_permission - Decision: If authorized, passes to handler; if not, returns 403/404
Permission Check Logic (check_api_permission)
pub async fn check_api(arg: RoleApiCheckInfo) -> bool {
let model = sys_role_api::Entity::find()
.filter(
Condition::all()
.add(sys_role_api::Column::RoleId.eq(arg.role_id))
.add(sys_role_api::Column::Api.eq(arg.api))
.add(sys_role_api::Column::Method.eq(arg.method)),
)
.one(DB().await)
.await
.unwrap();
model.is_some()
}How to Configure API Permissions
- Auto-registration: At startup, the routing system's introspection feature auto-syncs all protected API paths/methods to the database
- Role Management: Admin creates roles (e.g., "Content Editor", "Finance Specialist")
- Permission Assignment: Admin selects which APIs a role can access
- Save & Apply: The
sys_role_apitable stores the associations; permission checks happen in real-time
This RBAC system removes permission management complexity from code, making it a dynamic, business-user-configurable function.