基于RUL的权限管理

我想在写shiro权限管理认证前,先来一个基于URL实现的权限管理控制。

一、基于URI的权限业务逻辑

 实现思路:
       将系统操作的每个url配置在权限表中,将权限对应到角色,将角色分配给用户,用户访问系统功能通过Filter进行过虑,过虑器获取到用户访问的url,只要访问的url是用户分配角色中的url则放行继续访问。
具体逻辑看下面一张表。

二、环境搭建(数据表)

思维已经清晰,接下来通过代码来实现具体业务逻辑。
   开发环境
          JDK1.8
          Eclipse
          Maven
   技术架构:SpringMVC+Mybatis+jQuery easyUI

数据库

MySQL数据库中创建表:用户表、角色表、权限表(实质是权限和资源的结合)、用户角色关系表、角色权限关系表。

(1)具体表

  sys_user  用户表(这里明文密码都是:111111)

  sys_role  角色表

 sys_user_role 权限表

sys_permission 权限表

 sys_role_permission  角色权限关系表

三、用户认证

   1.login.action用户登录页面

<BODY >
<FORM id="loginform" name="loginform" action="?loginsubmit.action"
method="post">
<TABLE class="tab" border="0" cellSpacing="6" cellPadding="8">
<TBODY>
<TR>
<TD>用户名:</TD>
<TD colSpan="2"><input type="text" id="usercode"
name="usercode" style="WIDTH: 130px" /></TD>
</TR>
<TR>
<TD>密 码:</TD>
<TD><input type="password" id="pwd" name="password" style="WIDTH: 130px" />
</TD>
</TR>
<TR>
<TD>验证码:</TD>
<TD><input id="randomcode" name="randomcode" size="8" /> <img
id="randomcode_img" src="${baseurl}validatecode.jsp" alt=""
width="56" height="20" align='absMiddle' /> <a
href=javascript:randomcode_refresh()>刷新</a></TD>
</TR> <TR>
<TD colSpan="2" align="center"><input type="sumbit"
value="登 录" />
</TD>
</TR>
</TBODY>
</TABLE>
</FORM>
</BODY>

login.jsp

   2、SpringMVC配置过滤器

<!-- 用户身份校验的拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.jincou.controller.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>

3、LoginInterceptor过滤器

public class LoginInterceptor implements HandlerInterceptor {

    // 在进入controller方法之前执行
// 进行身份认证校验拦截,如果拦截不放行,controller方法不再执行
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception { // 校验用户访问是否是公开资源地址(无需认证即可访问)
List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL"); // 用户访问的url(这里用户登录页面login.action,和登录提交页面loginsubmit.action属于公开访问页面,直接发行)
String url = request.getRequestURI();
for (String open_url : open_urls) {
if (url.indexOf(open_url) >= 0) {
// 如果访问的是公开 地址则放行
return true;
}
} // 校验用户身份是否认证通过
HttpSession session = request.getSession();
ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
if (activeUser != null) {
// 用户已经登陆认证,放行
return true;
}
// 跳转到登陆页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,
response);
return false;
} }

(1)anonymousURL.properties配置文件

#不需要登录就可以访问的页面:比如登录页面,登陆提交的地址,网站首页等
login.action=登录页面
loginsubmit.action=登陆提交按钮的地址

配置文件

4、LoginControl控制层

/**
* 获得用户名,密码,验证码进行用户验证,验证通过就把该用户放到session中
*/
@Controller
public class LoginController { @Autowired
private SysService sysService ; //用户登陆提交
@RequestMapping("/loginsubmit")
public String loginsubmit(HttpSession session,String usercode,String password,String randomcode) throws Exception{ //校验验证码
//从session获取正确的验证码(因为验证码是从前端生成,传到后端)
String validateCode = (String)session.getAttribute("validateCode");
if(!randomcode.equals(validateCode)){
//抛出异常:验证码错误
throw new CustomException("验证码 错误 !");
}
//用户身份认证
ActiveUser activeUser = sysService.authenticat(usercode, password); //记录session
session.setAttribute("activeUser", activeUser); return "redirect:first.action";
}
}

   4.1ActiveUser实体类

/**
* 用户身份信息,获取通过用户名得到密码和菜单和页面权限
*/
public class ActiveUser implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String userid;//用户id
private String usercode;// 用户账号
private String username;// 用户名称 private List<SysPermission> menus;// 菜单
private List<SysPermission> permissions;// 权限
//set和get方法
}

ActiveUser

 5.SysServiceImpl实现类

//@Override
public ActiveUser authenticat(String usercode, String password)
throws Exception { //账号和密码非空校验
//.... SysUserExample sysUserExample = new SysUserExample();
SysUserExample.Criteria criteria = sysUserExample.createCriteria();
criteria.andUsercodeEqualTo(usercode);
List<SysUser> userList = sysUserMapper.selectByExample(sysUserExample);
if(userList == null || userList.size()<=0){
throw new CustomException("账号不存在!");
}
SysUser sysUser = userList.get(0);
//密码
String password_fromdb = sysUser.getPassword(); //输入 密码 和数据库密码 比较(因为数据库加过密所以这里也加密后进行比较)
if(!password_fromdb.equalsIgnoreCase(new MD5().getMD5ofStr(password))){
throw new CustomException("账号或密码 错误 !");
}
//认证通过,返回用户身份
ActiveUser activeUser = new ActiveUser();
activeUser.setUserid(sysUser.getId());
activeUser.setUsername(sysUser.getUsername());
activeUser.setUsercode(sysUser.getUsercode()); //菜单列表
List<SysPermission> menus = sysPermissionMapperCustom.findMenuByUserid(sysUser.getId());
activeUser.setMenus(menus);
//权限列表
List<SysPermission> permissions = sysPermissionMapperCustom.findPermissionByUserid(sysUser.getId());
activeUser.setPermissions(permissions);
//获得用户菜单和权限列表
return activeUser;
}

总结:     

用户认证的思路很简单:
(1)判断用户登录是否成功,成功将用户信息放入session中,登录后点击其它页面,过滤器会看session是否存在用户,存在则放行。
(2)如果你没有登录,点击其它非公共页面,那过滤器会发现session中没有用户信息,则跳转到登录页面。

三、权限管理

    既你登录认证通过后,根据用户id从数据库中获取用户权限范围的URL,将URL的集合存储在activeUser中并存在session中。

     1.springMVC配置权限认证过滤器

<!-- 用户登陆成功后的资源权限拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.jincou.controller.interceptor.PermissionInterceptor"></bean>
</mvc:interceptor>

      2、PermissionInterceptor过滤器

public class PermissionInterceptor implements HandlerInterceptor {

    // 在进入controller方法之前执行
// 用户权限拦截,如果拦截不放行,controller方法不再执行
// 进入action方法前要执行
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// TODO Auto-generated method stub
// 用户访问地址:
String url = request.getRequestURI(); // 校验用户访问是否是公开资源地址(无需认证即可访问)
List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
// 用户访问的url
for (String open_url : open_urls) {
if (url.indexOf(open_url) >= 0) {
// 如果访问的是公开 地址则放行
return true;
}
}
//从 session获取用户公共访问地址(认证通过无需分配权限即可访问)
List<String> common_urls = ResourcesUtil.gekeyList("commonURL");
// 用户访问的url
for (String common_url : common_urls) {
if (url.indexOf(common_url) >= 0) {
// 如果访问的是公共地址则放行
return true;
}
}
// 从session获取用户权限信息 HttpSession session = request.getSession(); ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser"); // 取出session中权限url
// 获取用户操作权限
List<SysPermission> permission_list = activeUser.getPermissions();
// 校验用户访问地址是否在用户权限范围内
for (SysPermission sysPermission : permission_list) {
String permission_url = sysPermission.getUrl();
if (url.contains(permission_url)) {
return true;
}
} // 跳转到无权访问页面
request.getRequestDispatcher("/refuse.jsp").forward(
request, response);
return false;
} }

   (1)commonURL配置文件

#用户公共访问地址指的是用户登录后,有些页面也是不需要配置权限的,每个用户都会有的页面:比如:个人中心,退出页面等
first.action=系统页面
logout.action=退出页面

配置文件

总结:   

权限认证的思路:
   (1)当用户登录成功后,因为上面ActiveUser对象,里面有用户可以访问哪些菜单,所以页面也只会显示这些菜单。
   (2)当我用户浏览我没有权限的URL页面,那么PermissionInterceptor会判断我没有这个页面的权限,直接调整到无权访问页面。

四、一些细节

1、前段页面是如何做到当前用户可以获得哪些菜单(可以循环遍历)

<c:if test="${activeUser.menus!=null }">
<c:forEach items="${activeUser.menus }" var="menu">
<a href="${pageContext.request.contextPath }/${menu.url }" >${menu.name }</a>
</c:forEach>
</c:if>

2、验证下"zhangsan"用户能看到的菜单是否正确

(1)先看没有做权限页面的菜单

(2)再看做了权限管理的页面

(3)那到底是不是这样?(数据查询正确)

 github地址https://github.com/yudiandemingzi/URLquanxian

想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。少校【3】

【shiro】(2)---基于RUL的权限管理的更多相关文章

  1. 基于DDDLite的权限管理OpenAuth.net 1.0版正式发布

    距离上一篇OpenAuth.net的文章已经有5个多月了,在这段时间里项目得到了很多朋友的认可,开源中国上面的Star数接近300,于是坚定了我做下去的信心.最近稍微清闲点,正式推出1.0版,并在阿里 ...

  2. 10.spring-boot基于角色的权限管理页面实现

    10.spring-boot基于角色的权限管理页面实现

  3. Shiro 整合SpringMVC 并实现权限管理,登录和注销

    Shiro 整合SpringMVC 并且实现权限管理,登录和注销 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring S ...

  4. 基于云端的通用权限管理系统,SAAS服务,基于SAAS的权限管理,基于SAAS的单点登录SSO,企业单点登录,企业系统监控,企业授权认证中心

    基于云端的通用权限管理系统 SAAS服务 基于SAAS的权限管理 基于SAAS的单点登录SSO 基于.Net的SSO,单点登录系统,提供SAAS服务 基于Extjs 4.2 的企业信息管理系统 基于E ...

  5. SpringBoot整合Shiro实现基于角色的权限访问控制(RBAC)系统简单设计从零搭建

    SpringBoot整合Shiro实现基于角色的权限访问控制(RBAC)系统简单设计从零搭建 技术栈 : SpringBoot + shiro + jpa + freemark ,因为篇幅原因,这里只 ...

  6. devops-jenkins基于角色的权限管理RBAC

    一. devops-jenkins基于角色的权限管理RBAC 1 安装角色的rbac角色管理  1.1) 点击系统管理 1.2) 选择插件管理 1.3) 选择可选插件,输入role搜索 1.4) 选择 ...

  7. 基于RBAC实现权限管理

    基于RBAC实现权限管理 技术栈:SpringBoot.SpringMVC RBAC RBAC数据库表 主体 编号 账号 密码 001 admin 123456 资源 编号 资源名称 访问路径 001 ...

  8. (十二)整合 Shiro 框架,实现用户权限管理

    整合 Shiro 框架,实现用户权限管理 1.Shiro简介 1.1 基础概念 1.2 核心角色 1.3 核心理念 2.SpringBoot整合Shiro 2.1 核心依赖 2.2 Shiro核心配置 ...

  9. Shiro集成SSM基于动态URL权限管理(二)

    这个案例基于上一个demo扩展而来.所以数据库表,在Shiro集成SSM基于URL权限管理(一)开篇的一致.如果上个demo操作的建议重新导入一次,避免出现问题. 而这次都不是通过固定写在方法上的注解 ...

随机推荐

  1. Fiddler将笔记本设置代理,抓取手机网络请求包

    第一步:下载fiddler,下载地址:http://www.telerik.com/download/fiddler 第二步:安装fiddler,略过... 第三步:启动fiddler,启动后界面如下 ...

  2. java线程池ThreadPoolExecutor使用简介

    一.简介线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:ThreadPoolExecutor(int corePoolSize, int m ...

  3. Linux版Matlab R2015b的bug——脚本运行的陷阱(未解决)

    0 系统+软件版本 系统:CentOS 6.7 x64, 内核 2.6.32-573.el6.x86_64软件:Matlab R2015b(包括威锋网和东北大学ipv6下载的资源,都测试过) 1 脚本 ...

  4. Cocos2d-x环境搭建

    资源列表 官网上下载最新的cocos2d-x-3.3. 安装JDK,Eclipse,CDT插件,ADT插件. 下载Android SDK,更新.因为国内经常访问不了google,用vpn速度也有点慢. ...

  5. 使用photoshop,把图片背景变成透明

    鄙人使用的是photoshop CS6,win7系统,好了废话不多说,我们开始吧 1.打开photoshop,选择一个要编辑的图片 2.在右下角的图层面板上用鼠标左键快速双击背景图层为图片解锁 3.在 ...

  6. Objective-C 类的继承、方法的重写和重载

    一.类的继承 Objective-c中类的继承与C++类似,不同的是Objective-c不支持多重继承,一个类只能有一个父类,单继承使Objective-c的继承关系很简单,易于管理程序.Objec ...

  7. .net验证控件

    一.客户端验证(用户体验,减少服务器端压力) 二.服务器端验证(防止恶意攻击,客户端js很容易被绕过) 验证控件:RequiredFieldValidator:字段必填:RangeValidator: ...

  8. winform下载网页代码

    1:webClient client=new WebClient(); client.Downloadstring(地址) client.Downloadfile(地址,保存路径) 2:后台线程dow ...

  9. WPF界面设计技巧(6)—玩玩数字墨水手绘涂鸦

    原文:WPF界面设计技巧(6)-玩玩数字墨水手绘涂鸦 想让你的程序支持鼠标及手写笔涂鸦吗?只要敲入“<InkCanvas/>”这几个字符,你就会领悟什么叫“很好很强大”,今天我们来做一个手 ...

  10. array_walk与array_map 的不同 array_filter

      array_walk 主要是要对数组内的每个值进行操作,操作结果影响原来的数组 array_map主要是对数组中的值进行操作后返回数组,以得到一个新数组 wallk 可以没有返回值 map要有,因 ...