如何设计一个的系统权限(用户,角,权限,渠道授权【PC、PAD、PHONE、WAP】)...

如何设计⼀个的系统权限(⽤户,⾓⾊,权限,渠道授权【PC、PAD、PHONE、WAP】)...
前⾔
随着移动互联⽹的发展,系统使⽤者从PC端移动到了移动端,如何控制权限系统成为了⼀个问题。现将JSUP【java2e source unify platform】权限设计思路写出,⼀来记录⾃⼰的程序开发之路,⼆来能给予⼤家帮助【理想状态哈】。
分析:
说到权限管理,⼤家肯定会想到很多,⽹络资源也很多,专业⼀点的如基于RBAC模型,但是对于想直接设计系统权限,还是很困难。简单⼀点⼉的设计,便就是⽤户与权限,这样便能保证⼀个⽤户拥有怎么样的权限。使⽤频次⽐较低,⽤户使⽤数较少时,这种设计也可解决问题,⽅便快捷嘛。
假设⼀种场景,现公司有⼀套内容管理系统,如果公司⾥⾯所有员⼯都有这样的权限呢,每⼀个⼈都要配置?那是⼀件很痛苦的事情。因此再添加⼀个中间物--⾓⾊,把某些⼈归为⼀类,然后再把权限分配给⾓⾊。⾓⾊属下的⽤户也就拥有了权限。将这种场景可以举⼀反三很多。
这就是⼤家熟知的⽤户关联⾓⾊,⾓⾊管理权限。
所谓渠道授权,即给定某⼀渠道分配Appkey以及秘钥进⾏控制,并且可以限定某⼀渠道请求的服务次数。由于渠道控制并不是系统权限的核⼼,故以下描述中,不作为重点描述。
鉴于此,有了⽤户、⾓⾊、权限、渠道,那么应该考虑⼀下这⼏个概念之间的关系。
1、        ⼀个⽤户可以拥有多个⾓⾊。多对多关系
2、        ⼀个⾓⾊可以拥有多个权限。多对多关系
3、        ⼀个⽤户可以在多个渠道使⽤。多对多关系【⾮重点】neor
不同的应⽤场合,你可能会想出不同的需求,提了⼀个新的需求以后,可能会发现原来的设计没⽅法实现了,其实不⽤考虑那么复杂,借⽤RBAC模式设计,其实问题很简单,⽆⾮就是其实就是Who、What、How的问题。
实现效果图:
系统登录
⽤户可以进⾏⾓⾊选择进⼊系统。效果图如下所⽰:
权限管理
JSUP平台内权限管理可以进⾏CURD操作,⽅便管理员实时维护,主要功能有查询、增加、修改、删除、关联。维护的粒度为按钮级别。关联功能主要可以⽤于流程性功能时使⽤。系统内所有操作均可以抽象为资源,如菜单资源、按钮资源、导航资源、系统级资源【⽆需授权即可使⽤】。效果图如下:
⾓⾊管理
⾓⾊可以理解为权限集合,JSUP内⾓⾊功能,也可以理解为⾓⾊组以及⾓⾊,⾓⾊之间从在⽗⼦关系。效果图如下:
⽤户管理
⽤户管理功能只为登录凭证,正常此功能应该涉及员⼯信息、部门信息、职务信息、级别信息等。对⽤户登录凭证有三种⽅式限定,账户是否激活,登录账户是否过期,密码是否过期。如果⽤户输⼊错误密码次数过多,系统会锁定该账户,禁⽌登录系统。
⼀个⽤户可以分配多个⾓⾊,只⽤⽤户选定某⼀⾓⾊时⽅可登录系统。
数据模型设计【mysql版本】
要实现效果图,后台需要表12张,员⼯信息表、员⼯职务表、组织结构表、⽤户信息表、⾓⾊信息表、权限信息表、渠道信息表、Appkey 秘钥表、⽤户与⾓⾊关联表、⾓⾊与权限管理表、权限关联表、渠道与⾓⾊关联表。
代码实现
所⽤语⾔为JAVA,本⽂中使⽤到的技术有Spring Security、Ibatis、JQuery、HTML5。本⽂中设计代码为关键代码,并⾮全部实现。需要完整代码,可以联系作者。
权限控制框架⽬前⽐较流⾏的有两种Spring Security以及Shiro。本⽂使⽤Spring Security。
Xml配置
<beans:bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider" >
<beans:property name="userDetailsService" ref="securityService"/>
<beans:property name="userLoginTraceService" ref="securityTraceService"/>
<beans:property name="passwordEncoder" ref="passwordEncoder"/>
<!--<beans:property name="userCache" ref="userCache"/>-->
</beans:bean>
<!--载⼊⽤户信息-->
<beans:bean id="securityService" class="com.jsup.service.bo.security.service.impl.SecurityServiceImpl"/>
<!--记录登录⽇志-->
<beans:bean id="securityTraceService" class="com.jsup.service.bo.security.service.impl.SecurityTraceServiceImpl"/>
<!--密码验证-->
<beans:bean id="passwordEncoder" class="org.springframework.ding.Md5PasswordEncoder"/> UserDetailsService类实现
@Resource(name = "securityDaoHibernater")
脑根private ISecurityDao securityDao;
@Resource(name = "roleDaoHibernater")
private IRoleDao roleDao;
@Override
public UserDetails loadUserByUsername(String username,Authentication authentication) throws UsernameNotFoundException {
return loadUser(username,authentication,"");
return loadUser(username,authentication,"");
}
@Override
public void recordPwdErrorTimes(Object username, Authentication authentication) throws UsernameNotFoundException {    Account _account = getAccountForCode((String)username);
Integer num = _ErrorTimes() == null ? 0 : _ErrorTimes();
_account.setErrorTimes(++num);
if (calculateIsLocked(_ErrorTimes())){
_account.setIslocked(ConstantPool.SYS_ACCOUNT_INFO_ISLOCKED_VALID);
}
_account.setUpdateDate(new Date());
this.securityDao.update(_account);
楼顶钢筋如何防锈
}
@Override
public void clearPwdErrorTimes(Object username) throws UsernameNotFoundException {
Account _account = getAccountForCode((String)username);
Integer num = _ErrorTimes() == null ? 0 : _ErrorTimes();
if (num > 0){
_account.setErrorTimes(0);
_account.setUpdateDate(new Date());
this.securityDao.update(_account);
}
}
public UserDetails loadUser(String code, Authentication authentication, String ip) {
Account account = new Account(code);
account = loadUser(account, authentication);
return account;
}
public Account loadUser(Account account, Authentication authentication) {
Account _account = Code());
if (_account == null || StringUtils.isEmpty(_Code())) {
throw new UsernameNotFoundException("UsernameNotFound");
} else {
account.initAccount(_account);
account.setRoles(new HashSet());
}
if (_Roles() != null && _Roles().size() > 0) {
Role role;
for (Iterator iterator = _Roles().iterator(); iterator.hasNext(); ) {
role = (Role) ();
List list = new Authorities());
String roleCode = (((0)).getAuthority();
if (StringUtils.Code(),roleCode))
}
}
return account;
}
public Account getAccountForCode(String code) {
AccountForCode(code);
}
/
**
* 判断密码错误次数是否已经超限
* @param errorTimes 密码错误次数
* @return boolean true:超限 false:未超限
*/
private boolean calculateIsLocked(Integer errorTimes){
boolean isLocked = false;
boolean isLocked = false;
//错误次数可以扩展为表数据维护,数据存放与servletContext中
if (errorTimes >= 5){
isLocked = true;
}
return isLocked;
}
合成塔UserDetails类实现
@Override
public boolean isAccountNonExpired() {
return new Date().before(getCodeOverdueDate());
}
电子倾斜仪@Override
public boolean isAccountNonLocked() {
return ConstantPool.SYS_ACCOUNT_INFO_ISLOCKED_INVALID.equals(getIslocked()); }
@Override
public boolean isCredentialsNonExpired() {
return new Date().before(getPwdOverdueDate());
}
@Override
public boolean isEnabled() {
return ConstantPool.SYS_ACCOUNT_INFO_ISENABLED_VALID.equals(getIsEnabled()); }
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
if(getRoles() == null || getRoles().size() == 0) {
return null;
}
else {
Set<GrantedAuthority> sgset = getRoles();
List<GrantedAuthority> sglist = new ArrayList<GrantedAuthority>(sgset);
return sglist;
}
}
@Override
冰点渗透压
public String getUsername() {
EmpBaseInfo() == null ? "" : EmpBaseInfo().getName();
}
UserLoginTraceService类实现

本文发布于:2024-09-21 03:15:16,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/99280.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:权限   系统   设计
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议