WCF技术实现基于角色的访问控制
第一次写,小紧张!
即将毕业了,现在将我毕业设计中用到的小的编程技术以及自己的一些理解分享出来,希望可以做点小贡献。
首先要感谢网上各路大神无私的分享,没有你们,就没有我的收获。
在大四之前,对于编程只是学习过简单的C语言,从来没有接触过工程实践。最后的毕业设计肯定要开发程序,于是认真学习了一段时间。
我的毕业设计是开发一个信息管理系统,希望简单实现对学生信息的管理。系统的前端决定使用MVC模式(当下比较流行,但是好难学!),后台的管理用到了WCF技术,体现一种SOA思想。
今天主要讲讲WCF技术如何实现基于角色的访问控制,这里只是涉及基本原理,高手勿喷!
一、基于角色访问控制原理
(1)用户
用户是指系统的使用者,是一个能够对系统进行访问和操作的实体。
(2)角色
角色是整个RBAC模型中的关键,角色是用户和系统权限中间的媒介,将用户和系统权限相分离,起桥梁及纽带的作用。角色可以被分配给用户,进而和用户建立关联;角色也可以被分配权限,进而和访问权限建立关联。
在实际的系统中,用户可以根据需要被分配多个角色,比如一个人既是单位的董事长又是单位的足球队长;角色也可以根据需要被分配多个权限,比如部门经理角色可以被分配人事任免权和决策权。
(3)权限
权限是指系统使用者对系统资源进行访问和操作的能力,在RBAC中,用户通过被分配相应的角色而间接获得了所需的权限。
(4)会话
会话在访问控制中起标记作用,用户和角色通过建立持续一段时间的会话来进行关联。一个用户在一次操作周期中,可以通过一个会话关联多个不同的角色,当然也可以通过多个不同的会话关联更多的角色。而用户的权限就是这些关联的角色的权限之和。
(5)角色等级
角色等级RH(Role Hierarchy)在现实的系统中可以直接体现出使用该系统的企业或单位的权力等级和责任划分,在程序设计中也方便通过继承进行授权。
二、访问控制服务功能模块设计
该服务按照功能可以划分为如下几个部分:用户管理模块、角色管理模块、授权管理模块和权限判定模块。
三、授权管理流程设计
四、访问控制流程设计
五、数据库设计
下图是VS中LINQ to SQL类的设计图,这个类用于连接SQL Server数据库,好用,推荐!
六、WCF契约设计
在下文的数据契约中,权限中有Controller和Action两个变量,这是因为我的这个WCF访问控制后台是和MVC前端结合的,大家在用的时候,需要根据自己的程序来设计权限中的变量。
1 [ServiceContract] 2 public interface IServiceAuthenticate 3 { 4 //用户注册,输入用户信息和会话信息进行用户注册 5 [OperationContract] 6 string Register(UserInfos userinfo, SessionInfos sessioninfo); 7 //用户删除,输入用户信息进行用户删除 8 [OperationContract] 9 string DeleteUser(UserInfos userinfo); 10 //用户登录,输入用户信息和会话信息进行用户登录 11 [OperationContract] 12 string Login(UserInfos userinfo, SessionInfos sessioninfo); 13 //用户登出,输入会话信息进行用户登出 14 [OperationContract] 15 string Logout(SessionInfos sessioninfo); 16 //状态查询,输入会话信息查询当前用户的登录和操作状态 17 [OperationContract] 18 string StateQuery(SessionInfos sessioninfo); 19 //创建角色,输入角色信息进行角色创建 20 [OperationContract] 21 string CreateRole(Role role); 22 //删除角色,输入角色信息进行角色删除 23 [OperationContract] 24 string DeleteRole(Role role); 25 //用户角色分配,输入用户信息和角色信息为用户分配角色 26 [OperationContract] 27 string CreateUserRole(UserInfos userinfo, Role role); 28 //删除用户角色分配,输入用户信息和角色信息删除特定的用户角色关系 29 [OperationContract] 30 string DeleteUserRole(UserInfos userinfo, Role role); 31 //角色权限分配,输入角色信息和权限信息为特定角色分配权限 32 [OperationContract] 33 string CreateRoleAuthority(Role role, Authority authority); 34 //删除角色权限分配,输入角色信息和权限信息删除特定的角色权限关系 35 [OperationContract] 36 string DeleteRoleAuthority(Role role, Authority authority); 37 //权限判定,输入会话信息和权限信息判定当前用户有无相应的权限 38 [OperationContract] 39 bool AuthorityJudge(SessionInfos sessioninfo, Authority authority); 40 41 } 42 43 //再定义几个常用的数据契约 44 [DataContract] 45 public class UserInfos 46 { 47 [DataMember] 48 public string Name { get; set; } 49 [DataMember] 50 public string HashPWD { get; set; } 51 } 52 [DataContract] 53 public class SessionInfos 54 { 55 [DataMember] 56 public string IP { get; set; } 57 [DataMember] 58 public string Browser { get; set; } 59 60 } 61 [DataContract] 62 public class Role 63 { 64 [DataMember] 65 public string RoleName { get; set; } 66 [DataMember] 67 public string Father { get; set; } 68 [DataMember] 69 public int RoleLevel { get; set; } 70 } 71 [DataContract] 72 public class Authority 73 { 74 [DataMember] 75 public string ActionName { get; set; } 76 [DataMember] 77 public string ControllerName { get; set; } 78 }
七、各个功能模块实现
我在开发时使用的SQL Server 2016,数据库连接使用的是LINQ to SQL,因此在程序开头需要定义连接:
UserDataClassesDataContext db = new UserDataClassesDataContext();
1、用户管理功能实现
1 //用户注册 2 public string Register(UserInfos userinfos,SessionInfos sessioninfos) 3 { 4 if (db.UserInfo.Where(m => m.Name == userinfos.Name).Count() > 0) 5 return "User Existed"; 6 else 7 { 8 UserInfo rec=new UserInfo(); 9 10 rec.Name = userinfos.Name; 11 rec.HashPWD = userinfos.HashPWD; 12 rec.RegDateTime = DateTime.Now; 13 rec.RegBrowser = sessioninfos.Browser; 14 rec.RegIP = sessioninfos.IP; 15 16 db.UserInfo.InsertOnSubmit(rec); 17 db.SubmitChanges(); 18 19 return "Welcome new user:" + userinfos.Name; 20 21 } 22 } 23 24 //用户删除 25 public string DeleteUser(UserInfos userinfos) 26 { 27 var rec = db.UserInfo.FirstOrDefault(m => m.Name == userinfos.Name); 28 if (rec != null) 29 { 30 db.UserInfo.DeleteOnSubmit(rec); 31 db.SubmitChanges(); 32 return "Delete Success"; 33 } 34 else 35 return "User not Exist"; 36 }
2、角色管理功能实现
1 //创建角色 2 public string CreateRole(Role role) 3 { 4 if (db.RoleInfo.Where(m => m.RoleName == role.RoleName).Count() > 0) 5 return "Role Existed"; 6 else 7 { 8 RoleInfo rec = new RoleInfo(); 9 rec.RoleName = role.RoleName; 10 rec.CreateTime = System.DateTime.Now; 11 rec.Father = role.Father; 12 rec.RoleLevel = role.RoleLevel; 13 14 db.RoleInfo.InsertOnSubmit(rec); 15 db.SubmitChanges(); 16 return "Create Success"; 17 } 18 } 19 //删除角色 20 public string DeleteRole(Role role) 21 { 22 var rec = db.RoleInfo.FirstOrDefault(m => m.RoleName == role.RoleName); 23 if(rec!=null) 24 { 25 db.RoleInfo.DeleteOnSubmit(rec); 26 db.SubmitChanges(); 27 return "Delete Success"; 28 } 29 else 30 { 31 return "Role not Exist"; 32 } 33 }
3、授权管理功能实现
1 //创建用户-角色规则 2 public string CreateUserRole(UserInfos userinfo, Role role) 3 { 4 //先判断用户名是否存在 5 if (db.UserInfo.Where(m => m.Name == userinfo.Name).Count() > 0) 6 { 7 //再判断角色名是否存在 8 if(db.RoleInfo.Where(m => m.RoleName == role.RoleName).Count() > 0) 9 { 10 //再判断想要添加的规则是否存在 11 if (db.UserRole.Where(m => m.UserName == userinfo.Name && m.RoleName == role.RoleName).Count() > 0) 12 return "Rule Exist"; 13 else 14 { 15 //写入想要添加的用户-角色规则 16 UserRole rec = new UserRole(); 17 rec.UserName = userinfo.Name; 18 rec.RoleName = role.RoleName; 19 rec.CreateTime = System.DateTime.Now; 20 21 db.UserRole.InsertOnSubmit(rec); 22 db.SubmitChanges(); 23 //根据权限继承原理,将角色的子角色也赋给用户 24 List < RoleInfo> userrolelist= db.RoleInfo.Where(m => m.Father == role.RoleName).ToList(); 25 for(int i = 0; i < userrolelist.Count; i++) 26 { 27 UserRole rec2 = new UserRole(); 28 rec2.UserName = userinfo.Name; 29 rec2.RoleName = userrolelist[i].RoleName; 30 rec2.CreateTime = System.DateTime.Now; 31 db.UserRole.InsertOnSubmit(rec2); 32 db.SubmitChanges(); 33 } 34 return "Create Success"; 35 } 36 } 37 else 38 { 39 return "Role not Exist"; 40 } 41 } 42 else 43 { 44 return "User not Exist"; 45 } 46 } 47 //删除用户-角色规则 48 public string DeleteUserRole(UserInfos userinfo, Role role) 49 { 50 if(db.UserInfo.Where(m=>m.Name==userinfo.Name).Count()>0 51 &&db.RoleInfo.Where(m=>m.RoleName==role.RoleName).Count()>0) 52 { 53 var rec = db.UserRole.FirstOrDefault(m => m.UserName == userinfo.Name && m.RoleName == role.RoleName); 54 if(rec!=null) 55 { 56 db.UserRole.DeleteOnSubmit(rec); 57 db.SubmitChanges(); 58 return "Delete Suceess"; 59 } 60 else 61 { 62 return "Rule not Exist"; 63 } 64 } 65 else 66 { 67 return "Delete Fail"; 68 } 69 } 70 //创建角色-权限规则 71 public string CreateRoleAuthority(Role role, Authority authority) 72 { 73 //判断角色是否存在 if(db.RoleInfo.Where(m=>m.RoleName==role.RoleName).Count()>0) 74 { 75 //查询角色关联的所有规则,找出是否存在想要添加的规则 76 var rec= db.RoleAuthority.FirstOrDefault(m => m.RoleName == role.RoleName 77 && m.ActionName == authority.ActionName && m.ControllerName == authority.ControllerName); 78 79 if(rec!=null) 80 { 81 return "Rule Exist"; 82 } 83 //规则不存在,则添加 84 else 85 { 86 RoleAuthority rec2 = new RoleAuthority(); 87 rec2.RoleName = role.RoleName; 88 rec2.ActionName = authority.ActionName; 89 rec2.ControllerName = authority.ControllerName; 90 rec2.CreateTime = System.DateTime.Now; 91 92 db.RoleAuthority.InsertOnSubmit(rec2); 93 db.SubmitChanges(); 94 return "Create Success"; 95 } 96 } 97 else 98 { 99 return "Role not Exist"; 100 } 101 } 102 //删除角色权限规则 103 public string DeleteRoleAuthority(Role role, Authority authority) 104 { 105 var rec = db.RoleAuthority.FirstOrDefault(m => m.RoleName == role.RoleName 106 && m.ActionName == authority.ActionName && m.ControllerName == authority.ControllerName); 107 if(rec==null) 108 { 109 return "Rule not Exist"; 110 } 111 else 112 { 113 db.RoleAuthority.DeleteOnSubmit(rec); 114 db.SubmitChanges(); 115 return "Delete Success"; 116 } 117 }
4、访问控制功能实现
1 //用户认证 2 public string Login(UserInfos userinfos, SessionInfos sessioninfos) 3 { 4 5 if (!(db.UserInfo.Where(m => m.Name == userinfos.Name).Count() > 0)) 6 { 7 return "Please Register Firstly!"; 8 } 9 else 10 { 11 UserInfo rec = new UserInfo(); 12 rec = db.UserInfo.Where(m => m.Name == userinfos.Name).First(); 13 14 if (rec.HashPWD == userinfos.HashPWD) 15 { 16 AuthInfo authrec = new AuthInfo(); 17 authrec.Name = userinfos.Name; 18 authrec.IP = sessioninfos.IP; 19 authrec.Browser = sessioninfos.Browser; 20 authrec.AuthTime = DateTime.Now; 21 authrec.LastAuthTime = DateTime.Now; 22 authrec.LogOffTime = null; 23 24 db.AuthInfo.InsertOnSubmit(authrec); 25 db.SubmitChanges(); 26 return "Authenticate Success!"; 27 } 28 else 29 { 30 return "Authenticate Fail..."; 31 } 32 33 } 34 } 35 //用户登出 36 public string Logout(SessionInfos sessioninfos) 37 { 38 AuthInfo authrec = new AuthInfo(); 39 authrec = db.AuthInfo.Where(m => m.Browser == sessioninfos.Browser && m.IP == sessioninfos.IP 40 &&(m.LastAuthTime>System.DateTime.Now.AddMinutes(-60)) 41 && m.LogOffTime == null).First(); 42 43 authrec.LogOffTime = DateTime.Now; 44 45 db.SubmitChanges(); 46 return "Logout successed"; 47 48 } 49 //用户状态查询,便于获取当前用户的信息 50 public string StateQuery(SessionInfos sessioninfos) 51 { 52 if (db.AuthInfo.Where(m => m.Browser == sessioninfos.Browser && m.IP == sessioninfos.IP 53 && (m.LastAuthTime > System.DateTime.Now.AddMinutes(-60)) 54 &&m.LogOffTime==null).Count() > 0) 55 { 56 AuthInfo authrec = new AuthInfo(); 57 authrec = db.AuthInfo.Where(m => m.Browser == sessioninfos.Browser && m.IP == sessioninfos.IP 58 && (m.LastAuthTime>System.DateTime.Now.AddMinutes(-60)) 59 && m.LogOffTime == null).First(); 60 61 authrec.LastAuthTime = System.DateTime.Now; 62 db.SubmitChanges(); 63 return authrec.Name + ",you has logged in."; 64 } 65 else 66 { 67 return "Please login or register"; 68 } 69 } 70 //用户权限判定,决定是否授权 71 public bool AuthorityJudge(SessionInfos sessioninfo, Authority authority) 72 { 73 bool flag = false; 74 //抓取当前用户 75 var authinforec = db.AuthInfo.FirstOrDefault(m => m.IP == sessioninfo.IP && m.Browser == sessioninfo.Browser 76 &&m.LogOffTime==null); 77 //查询用户的所有角色 78 var userrolerec = db.UserRole.Where(m => m.UserName == authinforec.Name).ToArray(); 79 //遍历角色的所有权限,查询是否存在与请求权限相同的权限 80 for (int i = 0; i < userrolerec.Length;i++ ) 81 { 82 var roleauthorityrec = db.RoleAuthority.FirstOrDefault(m => m.RoleName == userrolerec[i].RoleName 83 && m.ActionName == authority.ActionName && m.ControllerName == authority.ControllerName); 84 //如果用户对应的角色存在相应权限,则授权 85 if (roleauthorityrec != null) 86 { 87 flag = true; 88 break; 89 } 90 else flag = false; 91 } 92 93 return flag; 94 }