C#+数据库 实现动态权限设置

devtools/2024/11/26 10:08:27/

将权限信息存储在数据库中,支持动态调整。根据用户所属的角色、特定的功能模块,动态加载权限”

1. 数据库设计

根据这种需求,可以通过以下表设计:

  • 用户表 (Users):存储用户信息。
  • 角色表 (Roles):存储角色信息。
  • 模块表 (Modules):存储系统的功能模块。
  • 权限表 (Permissions):存储权限信息。
  • 用户角色表 (UserRoles):存储用户和角色的关系,一个用户对应一个角色。
  • 角色权限表 (RolePermissions):存储角色与权限的关系,允许不同用户的权限定制。
  • 用户权限表 (UserPermissions):为每个用户定制权限(可覆盖角色权限)。
表结构
-- 用户表
CREATE TABLE Users (UserId INT PRIMARY KEY,UserName VARCHAR(100)
);-- 角色表
CREATE TABLE Roles (RoleId INT PRIMARY KEY,RoleName VARCHAR(100)
);-- 模块表
CREATE TABLE Modules (ModuleId INT PRIMARY KEY,ModuleName VARCHAR(100)
);-- 权限表
CREATE TABLE Permissions (PermissionId INT PRIMARY KEY,PermissionName VARCHAR(100)
);-- 用户角色表:每个用户对应一个角色
CREATE TABLE UserRoles (UserId INT,RoleId INT,FOREIGN KEY (UserId) REFERENCES Users(UserId),FOREIGN KEY (RoleId) REFERENCES Roles(RoleId)
);-- 角色权限表:角色与权限的关系,一个角色可以有多个权限
CREATE TABLE RolePermissions (RoleId INT,PermissionId INT,ModuleId INT,FOREIGN KEY (RoleId) REFERENCES Roles(RoleId),FOREIGN KEY (PermissionId) REFERENCES Permissions(PermissionId),FOREIGN KEY (ModuleId) REFERENCES Modules(ModuleId)
);-- 用户权限表:为用户定制权限,覆盖角色权限
CREATE TABLE UserPermissions (UserId INT,PermissionId INT,ModuleId INT,FOREIGN KEY (UserId) REFERENCES Users(UserId),FOREIGN KEY (PermissionId) REFERENCES Permissions(PermissionId),FOREIGN KEY (ModuleId) REFERENCES Modules(ModuleId)
);

2. 权限加载逻辑

  1. 用户角色:每个用户通过 UserRoles 表与一个角色关联。
  2. 角色权限:通过 RolePermissions 表为角色分配权限。
  3. 用户权限:通过 UserPermissions 表为用户定制权限,覆盖角色的默认权限。

3. 权限查询

  • 查询用户权限:首先通过 UserRoles 获取该用户的角色,再通过 RolePermissions 查询该角色的权限。然后,如果该用户有自定义权限,可以通过 UserPermissions 覆盖角色权限。
查询用户权限的顺序
  1. 查询用户所属角色。
  2. 查询该角色的权限。
  3. 查询该用户是否有自定义权限。
示例查询
-- 查询用户的角色
SELECT r.RoleId, r.RoleName
FROM Users u
JOIN UserRoles ur ON u.UserId = ur.UserId
JOIN Roles r ON ur.RoleId = r.RoleId
WHERE u.UserId = @UserId;-- 查询角色的权限
SELECT p.PermissionName
FROM RolePermissions rp
JOIN Permissions p ON rp.PermissionId = p.PermissionId
WHERE rp.RoleId = @RoleId AND rp.ModuleId = @ModuleId;-- 查询用户的自定义权限(如果有)
SELECT p.PermissionName
FROM UserPermissions up
JOIN Permissions p ON up.PermissionId = p.PermissionId
WHERE up.UserId = @UserId AND up.ModuleId = @ModuleId;

4. C# 代码实现

获取用户权限
public class PermissionService
{private string connectionString = "your_connection_string";// 获取用户权限public List<string> GetPermissionsByUserId(int userId, int moduleId){List<string> permissions = new List<string>();using (SqlConnection connection = new SqlConnection(connectionString)){connection.Open();// 获取用户角色string roleQuery = @"SELECT r.RoleIdFROM Users uJOIN UserRoles ur ON u.UserId = ur.UserIdJOIN Roles r ON ur.RoleId = r.RoleIdWHERE u.UserId = @UserId";SqlCommand roleCommand = new SqlCommand(roleQuery, connection);roleCommand.Parameters.AddWithValue("@UserId", userId);int roleId = (int)roleCommand.ExecuteScalar();// 获取角色权限string rolePermissionQuery = @"SELECT p.PermissionNameFROM RolePermissions rpJOIN Permissions p ON rp.PermissionId = p.PermissionIdWHERE rp.RoleId = @RoleId AND rp.ModuleId = @ModuleId";SqlCommand rolePermissionCommand = new SqlCommand(rolePermissionQuery, connection);rolePermissionCommand.Parameters.AddWithValue("@RoleId", roleId);rolePermissionCommand.Parameters.AddWithValue("@ModuleId", moduleId);SqlDataReader reader = rolePermissionCommand.ExecuteReader();while (reader.Read()){permissions.Add(reader.GetString(0));  // 角色权限}reader.Close();// 获取用户自定义权限(如果有)string userPermissionQuery = @"SELECT p.PermissionNameFROM UserPermissions upJOIN Permissions p ON up.PermissionId = p.PermissionIdWHERE up.UserId = @UserId AND up.ModuleId = @ModuleId";SqlCommand userPermissionCommand = new SqlCommand(userPermissionQuery, connection);userPermissionCommand.Parameters.AddWithValue("@UserId", userId);userPermissionCommand.Parameters.AddWithValue("@ModuleId", moduleId);SqlDataReader userReader = userPermissionCommand.ExecuteReader();while (userReader.Read()){permissions.Add(userReader.GetString(0));  // 用户自定义权限}}return permissions;}
}public class AccessControlService
{private PermissionService permissionService = new PermissionService();// 检查用户是否有权限public bool CanAccessModule(int userId, int moduleId, string requiredPermission){List<string> permissions = permissionService.GetPermissionsByUserId(userId, moduleId);return permissions.Contains(requiredPermission);  // 判断用户是否拥有特定权限}
}

5. 总结

  • 用户与角色的关系:一个用户对应一个角色,多个用户可以对应相同角色。
  • 角色与权限的关系:角色通过 RolePermissions 表分配权限,一个角色可以对应多个权限。
  • 用户自定义权限:通过 UserPermissions 表为用户定制权限,覆盖角色的默认权限。
  • 灵活的权限控制:用户的权限不仅继承自角色,还可以根据需要定制,确保权限控制的灵活性。

http://www.ppmy.cn/devtools/137091.html

相关文章

【深度学习】利用Java DL4J训练中文版的Word2Vec模型

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

【优选算法】前缀和

目录 一、[【模板】前缀和](https://www.nowcoder.com/practice/acead2f4c28c401889915da98ecdc6bf?tpId230&tqId2021480&ru/exam/oj&qru/ta/dynamic-programming/question-ranking&sourceUrl%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595…

Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?

大家好&#xff0c;我是锋哥。今天分享关于【Elasticsearch中的节点&#xff08;比如共20个&#xff09;&#xff0c;其中的10个选了一个master&#xff0c;另外10个选了另一个master&#xff0c;怎么办&#xff1f;】面试题。希望对大家有帮助&#xff1b; Elasticsearch中的节…

C语言蓝桥杯组题目

系列文章目录 文章目录 系列文章目录前言题目第一题.1, 2, 3, 4 能组成多少个互不相同且无重复数字的三位数&#xff1f;都是多少&#xff1f;思路 第二题: 一个整数&#xff0c;它加上100后是一个完全平方数&#xff0c;再加上168又是一个完全平方数&#xff0c;请问该数是多少…

如何更改手机GPS定位

你是否曾想过更改手机GPS位置以保护隐私、玩游戏或访问受地理限制的内容&#xff1f;接下来我将向你展示如何使用 MagFone Location Changer 更改手机GPS 位置&#xff01;无论是在玩Pokmon GO游戏、发布社媒贴子&#xff0c;这种方法都快速、简单且有效。 第一步&#xff1a;下…

设计模式——简单工厂模型、工厂模式、抽象工厂模式、单例模式、代理模式、模板模式

设计模式 面向接口编程&#xff0c;而不是面向实现。这个很重要&#xff0c;也是优雅的、可扩展的代码的第一步。 职责单一原则。每个类都应该只有一个单一的功能&#xff0c;并且该功能应该由这个类完全封装起来。 对修改关闭&#xff0c;对扩展开放。对修改关闭是说&#x…

前端高能组件库 Shadcn-UI

你是不是用 element-ui 或者 ant-design &#xff0c;然后&#xff0c;开发时常常遇到需要匹配设计稿时调样式的痛苦。 Shadcn-UI 结合tailwindcss &#xff0c;即可与让你享受组件同时随意的设置样式。 支持 VUE 官方地址&#xff1a;shadcn/ui 项目地址&#xff1a;https:…

【git】commit之后,想撤销commit

一、已经commit&#xff0c;想要回退到上一步 保留代码 git reset --soft HEAD^回退到具体的哪一步 HEAD^的意思是上一个版本&#xff0c;也可以写成HEAD~1如果你进行了2次commit&#xff0c;想都撤回&#xff0c;可以使用HEAD~2二、git reflog 查看 sha值 git reflog 回到…