基于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. amazeui分页

    <link rel="stylesheet" href="../../static/css/manage/amazeui.min.css" /> & ...

  2. 使用ajax实现html页面产品详情页文字具体内容

    <script type="text/javascript" src="Assets/js/jquery.min.js"></script&g ...

  3. Mac更改PHP默认目录

    在Mac上搭建了PHP服务器以后,默认的路径为/Library/WebServer/Documents下面,但这让人很不爽,我想修改到自己定义的路径下.经过好一番折腾,终于成功了. PHPEclips ...

  4. MySQL PROFILE 跟踪语句各阶段性能开销

    PROFILE  可以跟踪查询语句各个阶段 Time,IO,CPU,MEMORY 等资源使用情况,比较详细.所以系统一般不会记录太多.启用是全局的,所以每个连接都保持语句的资源使用情况. 查看 PRO ...

  5. gson的特殊用法

    1.gson包在处理 字符串转 Map 或者 List 的方法. List memberList = gson.fromJson(str,new TypeToken<List>() {}. ...

  6. mysql ERROR 1451 (23000)

    问题描述:报错如下:ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint提示有外键约束, ...

  7. while read line 查找指定日期的文件夹

    #!/bin/bash dir=/root/tmp targetdir=/root/tmp/tmp filenametxt=/tmp/filename.txt commandtxt=/tmp/comm ...

  8. 微信小程序——地图

    一:如何标点问题 地图模块需要用标点:官网API里面的wx.createMapContext(mapId, this)接口,且用官网Demo,小程序运行报错此时需要在wxml里面给map标签添加属性m ...

  9. MQTT

    1.IBM提出,适用于IOT,订阅和发布模式. 2.订阅和发布模式:这种模式是异步的形式,有些类似于邮件接发的形式,发送者将邮件发至代理,接收者如果没同时接收,也不影响发送者的二次发送. 3.主题模式 ...

  10. CDN随笔

    CDN的理解:(1)CDN (内容分发网络)加速用户获取数据的 系统(2)部署在离用户最近的网络节点上(3)命中CDN 不需要访问后端服务器(4)互联网公司自己搭建或租用