RBAC (Role-Based Access Control) 是企業級應用權限控制的標準模型。本文從核心概念、資料庫設計、關聯關係、存儲過程實作到 .NET WebService/Remoting 整合,提供完整落地方案。
用戶 ↔ 角色 ↔ 權限 三層解耦:
優勢:用戶異動只需調整角色關聯,權限變更只需調整角色權限,業務邏輯零修改。
CREATE TABLE User_Role (
UserRoleID VARCHAR(20) PK,
UserID VARCHAR(20) FK,
RoleID VARCHAR(20) FK,
UserRoleNote VARCHAR(200)
);
-- 範例資料
INSERT INTO User_Role VALUES
('1', '1', '01', '用戶「張三」分配角色「系統管理員」'),
('2', '2', '02', '用戶「李四」分配角色「監控人員」'),
('3', '2', '03', '用戶「李四」分配角色「調度人員」');
一個用戶可屬多角色,一個角色可含多用戶。
CREATE TABLE Role_Permission (
RolePermissionID VARCHAR(20) PK,
RoleID VARCHAR(20) FK,
PermissionID VARCHAR(20) FK,
RolePermissionNote VARCHAR(200)
);
-- 範例:系統管理員擁有完整權限
INSERT INTO Role_Permission VALUES
('1', '01', '0001', '角色「系統管理員」擁有「新增監控」'),
('2', '01', '0002', '角色「系統管理員」擁有「修改監控」'),
('3', '01', '0003', '角色「系統管理員」擁有「刪除監控」'),
('4', '01', '0004', '角色「系統管理員」擁有「查看監控」');
-- 監控人員僅有部分權限
INSERT INTO Role_Permission VALUES
('5', '02', '0001', '角色「監控人員」擁有「新增監控」'),
('6', '02', '0004', '角色「監控人員」擁有「查看監控」');
-- 1. 用戶表
CREATE TABLE Static_User (
UserID VARCHAR(20) PRIMARY KEY,
UserName VARCHAR(20) NOT NULL UNIQUE,
UserPwd VARCHAR(200) NOT NULL, -- 儲存雜湊值
LastSignTime DATETIME,
SignState INT DEFAULT 0, -- 0=離線, 1=在線
TicketID VARCHAR(128) -- 單點登入票據
);
-- 2. 角色表
CREATE TABLE Static_Role (
RoleID VARCHAR(20) PRIMARY KEY,
RoleName VARCHAR(20) NOT NULL UNIQUE,
RoleNote VARCHAR(200)
);
-- 3. 用戶-角色關聯表
CREATE TABLE Static_User_Role (
UserRoleID VARCHAR(20) PRIMARY KEY,
UserID VARCHAR(20) NOT NULL,
RoleID VARCHAR(20) NOT NULL,
UserRoleNote VARCHAR(200),
FOREIGN KEY (UserID) REFERENCES Static_User(UserID),
FOREIGN KEY (RoleID) REFERENCES Static_Role(RoleID)
);
-- 4. 權限表
CREATE TABLE Static_Permission (
PermissionID VARCHAR(20) PRIMARY KEY,
PermissionName VARCHAR(20) NOT NULL UNIQUE,
PermissionNote VARCHAR(200)
);
-- 5. 角色-權限關聯表
CREATE TABLE Static_Role_Permission (
RolePermissionID VARCHAR(20) PRIMARY KEY,
RoleID VARCHAR(20) NOT NULL,
PermissionID VARCHAR(20) NOT NULL,
RolePermissionNote VARCHAR(200),
FOREIGN KEY (RoleID) REFERENCES Static_Role(RoleID),
FOREIGN KEY (PermissionID) REFERENCES Static_Permission(PermissionID)
);
CREATE PROCEDURE CreatePermissionInfo
@PermissionName VARCHAR(20),
@PermissionNote VARCHAR(200)
AS
INSERT INTO Static_Permission (PermissionID, PermissionName, PermissionNote)
VALUES (NEWID(), @PermissionName, @PermissionNote);
CREATE PROCEDURE CreateUserInfo @UserName VARCHAR(20), @UserPwd VARCHAR(200); CREATE PROCEDURE ModifyUserInfo @UserID VARCHAR(20), @UserPwd VARCHAR(200); CREATE PROCEDURE DeleteUserInfo @UserID VARCHAR(20);
CREATE PROCEDURE CreateRoleInfo @RoleName VARCHAR(20), @RoleNote VARCHAR(200); CREATE PROCEDURE DeleteRoleInfo @RoleID VARCHAR(20);
-- 用戶-角色 CREATE PROCEDURE GrantUserRole @UserID VARCHAR(20), @RoleID VARCHAR(20), @Note VARCHAR(200); CREATE PROCEDURE DeleteUserRole @UserRoleID VARCHAR(20); -- 角色-權限 CREATE PROCEDURE GrantRolePermission @RoleID VARCHAR(20), @PermissionID VARCHAR(20), @Note VARCHAR(200); CREATE PROCEDURE DeleteRolePermission @RolePermissionID VARCHAR(20);
// 自定義 SoapHeader
public class AuthHeader : SoapHeader {
public string TicketID; // 攜帶票據而非明文密碼
}
// 服務端驗證
public class AuthService : WebService {
public AuthHeader AuthHeader;
[WebMethod, SoapHeader("AuthHeader")]
public string SecureMethod() {
if (AuthHeader == null || string.IsNullOrEmpty(AuthHeader.TicketID))
return "ERROR: Missing ticket";
// 呼叫 JudgeTicketPermission 存儲過程
bool hasPerm = CheckPermission(AuthHeader.TicketID, "SecureMethod");
return hasPerm ? "OK" : "ERROR: Permission denied";
}
}
// 客戶端調用
var svc = new AuthService();
svc.AuthHeader = new AuthHeader { TicketID = "user_ticket_from_login" };
var result = svc.SecureMethod();
// 客戶端:將票據放入 CallContext
CallContext.SetData("TicketID", userTicket);
// 遠端方法中取得
var ticket = CallContext.GetData("TicketID") as string;
if (string.IsNullOrEmpty(ticket) || !CheckPermission(ticket, methodName))
throw new SecurityException("Unauthorized");
關鍵點:實作 ILogicalThreadAffinative 介面的物件才能跨 AppDomain 傳遞。
// 權限管理
class PermissionInfoMng { CreatePermissionInfo(); }
// 用戶管理
class UserInfoMng { CreateUserInfo(); ModifyUserInfo(); DeleteUserInfo(); }
// 角色管理
class RoleInfoMng { CreateRoleInfo(); DeleteRoleInfo(); }
// 用戶-角色授權
class UserRoleMng { GrantUserRole(); DeleteUserRole(); }
// 角色-權限授權
class RolePermissionMng { GrantRolePermission(); DeleteRolePermission(); }
// 認證管理
class Authentication {
Login(userName, pwd) → ticket;
Logout();
ExceptionLogout();
}
RBAC 模型以「用戶-角色-權限」三層解耦,配合存儲過程封裝業務邏輯,實現了權限管理的標準化、可維護與擴展。落地時建議優先使用成熟框架 (ASP.NET Core Identity、Spring Security、Casbin),專注於業務權限模型的設計而非重複造輪子。