一、基于url权限管理流程【实现步骤】

  基于url拦截是企业中常用的权限管理方法,实现思路是:将系统操作的每个url配置在权限表中,将权限对应到角色,将角色分配给用户,用户访问系统功能通过Filter进行过虑,过虑器获取到用户访问的url,只要访问的url是用户分配角色中的url则放行继续访问。

二、环境搭建以及核心代码

https://github.com/bjlhx15/shiro.git

1、数据库

2、开发环境

3、系统工程框架

三、开发过程步骤

1、系统登录

主要功能:登录、记录用户session【包含用户信息,菜单信息,授权信息】

   1.1、系统登陆相当于用户身份认证,用户成功,要在session中记录用户的身份信息.

  1.2、操作流程:

         用户进行登陆页面

  输入用户名和密码进行登陆

  进行用户名和密码校验

    如果校验通过,在session记录用户身份信息

    根据用户信息记录菜单menus【用于功能菜单展示】,记录权限资源permissions【用户判断功能项】,一起放到session中

  1.3、激活用户基础类

public class ActiveUser implements java.io.Serializable {
private String userid;//用户id(主键)
private String usercode;// 用户账号
private String username;// 用户名称 private List<SysPermission> menus;// 菜单
private List<SysPermission> permissions;// 权限 public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getUsercode() {
return usercode;
} public void setUsercode(String usercode) {
this.usercode = usercode;
} public String getUserid() {
return userid;
} public void setUserid(String userid) {
this.userid = userid;
} public List<SysPermission> getMenus() {
return menus;
} public void setMenus(List<SysPermission> menus) {
this.menus = menus;
} public List<SysPermission> getPermissions() {
return permissions;
} public void setPermissions(List<SysPermission> permissions) {
this.permissions = permissions;
} }

  1.4、mapperr接口: 根据用户账号查询用户(sys_user)信息(使用逆向工程生成的mapper)

    使用逆向工程生成以下表的基础代码:

      

  1.5、service(进行用户名和密码校验)

    接口功能:根据用户的身份和密码 进行认证,如果认证通过,返回用户身份信息

    认证过程:

      根据用户身份(账号)查询数据库,如果查询不到用户不存在

      对输入的密码 和数据库密码 进行比对,如果一致,认证通过

    

  1.6、controller(记录session)    

    @RequestMapping("/login")
public String login(HttpSession session, String randomcode,String usercode,String password)throws Exception{ //校验验证码,防止恶性攻击
//从session获取正确验证码
String validateCode = (String) session.getAttribute("validateCode"); //输入的验证和session中的验证进行对比
if(!randomcode.equals(validateCode)){
//抛出异常
throw new CustomException("验证码输入错误");
} //调用service校验用户账号和密码的正确性
ActiveUser activeUser = sysService.authenticat(usercode, password); //如果service校验通过,将用户身份记录到session
session.setAttribute("activeUser", activeUser);
//重定向到商品查询页面
return "redirect:/first.action";
}

2、用户认证拦截

主要功能:放行匿名url、判断用户session是否存在

2.1、配置匿名访问url【anonymousURL.properties】

  

#配置逆向访问的url
login.action=用户登陆

2.2、编写认证拦截器

  用于用户认证校验、用户权限校验

package com.lhx.ssm.controller.interceptor;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import com.lhx.ssm.po.ActiveUser;
import com.lhx.ssm.util.ResourcesUtil; /**
*
* <p>Title: HandlerInterceptor1</p>
* <p>Description: 用户身份认证拦截器</p>
* @version 1.0
*/
public class LoginInterceptor implements HandlerInterceptor { //在执行handler之前来执行的
//用于用户认证校验、用户权限校验
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception { //得到请求的url
String url = request.getRequestURI(); //判断是否是公开 地址
//实际开发中需要公开 地址配置在配置文件中
//从配置中取逆名访问url List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
//遍历公开 地址,如果是公开 地址则放行
for(String open_url:open_urls){
if(url.indexOf(open_url)>=0){
//如果是公开 地址则放行
return true;
}
} //判断用户身份在session中是否存在
HttpSession session = request.getSession();
ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
//如果用户身份在session中存在放行
if(activeUser!=null){
return true;
}
//执行到这里拦截,跳转到登陆页面,用户进行身份认证
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); //如果返回false表示拦截不继续执行handler,如果返回true表示放行
return false;
}
//在执行handler返回modelAndView之前来执行
//如果需要向页面提供一些公用 的数据或配置一些视图信息,使用此方法实现 从modelAndView入手
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("HandlerInterceptor1...postHandle"); }
//执行handler之后执行此方法
//作系统 统一异常处理,进行方法执行性能监控,在preHandle中设置一个时间点,在afterCompletion设置一个时间,两个时间点的差就是执行时长
//实现 系统 统一日志记录
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("HandlerInterceptor1...afterCompletion");
} }

2.3、配置拦截器

  在springmvc.xml中配置拦截器:  

    <!--拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 用户认证拦截 -->
<mvc:mapping path="/**" />
<bean class="com.lhx.ssm.controller.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

3、授权

主要功能:放行匿名url、放行公共、获取用户session,授权资源判断

3.1、公共访问地址【commonURL.properties】

  在此配置文件配置公用访问地址,公用访问地址只要通过用户认证,不需要对公用访问地址分配权限即可访问。

#配置公用的访问地址
first.action=系统首页
logout.action=退出

3.2、获取用户权限范围菜单

  思路:在用户认证时,认证通过,根据用户id从数据库获取用户权限范围的菜单,将菜单的集合存储在session中。

  po在三中的1.3已添加menus等属性

  mapper xml

    <!-- 根据用户id查询菜单 -->
<select id="findMenuListByUserId" parameterType="string"
resultType="com.lhx.ssm.po.SysPermission">
SELECT
*
FROM
sys_permission
WHERE TYPE = 'menu'
AND id IN
(SELECT
sys_permission_id
FROM
sys_role_permission
WHERE sys_role_id IN
(SELECT
sys_role_id
FROM
sys_user_role
WHERE sys_user_id = #{id}))
</select>

  mapper接口

    //根据用户id查询菜单
public List<SysPermission> findMenuListByUserId(String userid)throws Exception;

  service接口:根据用户id查询用户权限的菜单

    @Override
public List<SysPermission> findMenuListByUserId(String userid)
throws Exception {
return sysPermissionMapperCustom.findMenuListByUserId(userid);
}

3.3、获取用户权限范围的url

  思路:在用户认证时,认证通过,根据用户id从数据库获取用户权限范围的url,将url的集合存储在session中。
  po在三中的1.3已添加permissions等属性

  mapper xml

    <!-- 根据用户id查询url -->
<select id="findPermissionListByUserId" parameterType="string"
resultType="com.lhx.ssm.po.SysPermission">
SELECT
*
FROM
sys_permission
WHERE TYPE = 'permission'
AND id IN
(SELECT
sys_permission_id
FROM
sys_role_permission
WHERE sys_role_id IN
(SELECT
sys_role_id
FROM
sys_user_role
WHERE sys_user_id = #{id}))
</select>

  mapper接口

//根据用户id查询权限url
public List<SysPermission> findPermissionListByUserId(String userid)throws Exception;

  service接口:根据用户id查询用户权限的菜单

    @Override
public List<SysPermission> findPermissionListByUserId(String userid)
throws Exception {
return sysPermissionMapperCustom.findPermissionListByUserId(userid);
}

3.4、用户认证通过后取出菜单和url放入ActiveUser,进而放入session

这里是三中的1.5 完善实现

package com.lhx.ssm.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.lhx.ssm.exception.CustomException;
import com.lhx.ssm.mapper.SysPermissionMapperCustom;
import com.lhx.ssm.mapper.SysUserMapper;
import com.lhx.ssm.po.ActiveUser;
import com.lhx.ssm.po.SysPermission;
import com.lhx.ssm.po.SysUser;
import com.lhx.ssm.po.SysUserExample;
import com.lhx.ssm.service.SysService;
import com.lhx.ssm.util.MD5; /**
*
* <p>Title: SysServiceImpl</p>
* <p>Description:认证和授权的服务接口 </p>
* @version 1.0
*/
public class SysServiceImpl implements SysService { @Autowired
private SysUserMapper sysUserMapper; @Autowired
private SysPermissionMapperCustom sysPermissionMapperCustom; @Override
public ActiveUser authenticat(String userCode, String password)
throws Exception {
/**
认证过程:
根据用户身份(账号)查询数据库,如果查询不到用户不存在
对输入的密码 和数据库密码 进行比对,如果一致,认证通过
*/
//根据用户账号查询数据库
SysUser sysUser = this.findSysUserByUserCode(userCode); if(sysUser == null){
//抛出异常
throw new CustomException("用户账号不存在");
} //数据库密码 (md5密码 )
String password_db = sysUser.getPassword(); //对输入的密码 和数据库密码 进行比对,如果一致,认证通过
//对页面输入的密码 进行md5加密
String password_input_md5 = new MD5().getMD5ofStr(password);
if(!password_input_md5.equalsIgnoreCase(password_db)){
//抛出异常
throw new CustomException("用户名或密码 错误");
}
//得到用户id
String userid = sysUser.getId();
//根据用户id查询菜单
List<SysPermission> menus =this.findMenuListByUserId(userid); //根据用户id查询权限url
List<SysPermission> permissions = this.findPermissionListByUserId(userid); //认证通过,返回用户身份信息
ActiveUser activeUser = new ActiveUser();
activeUser.setUserid(sysUser.getId());
activeUser.setUsercode(userCode);
activeUser.setUsername(sysUser.getUsername());//用户名称 //放入权限范围的菜单和url
activeUser.setMenus(menus);
activeUser.setPermissions(permissions); return activeUser;
} //根据用户账号查询用户信息
public SysUser findSysUserByUserCode(String userCode)throws Exception{
SysUserExample sysUserExample = new SysUserExample();
SysUserExample.Criteria criteria = sysUserExample.createCriteria();
criteria.andUsercodeEqualTo(userCode); List<SysUser> list = sysUserMapper.selectByExample(sysUserExample); if(list!=null && list.size()==1){
return list.get(0);
} return null;
} @Override
public List<SysPermission> findMenuListByUserId(String userid)
throws Exception {
return sysPermissionMapperCustom.findMenuListByUserId(userid);
} @Override
public List<SysPermission> findPermissionListByUserId(String userid)
throws Exception { return sysPermissionMapperCustom.findPermissionListByUserId(userid);
} }

3.5、菜单的动态显示需要前端配合

3.6、完整的授权拦截器代码【PermissionInterceptor】

package com.lhx.ssm.controller.interceptor;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import com.lhx.ssm.po.ActiveUser;
import com.lhx.ssm.po.SysPermission;
import com.lhx.ssm.util.ResourcesUtil; /**
*
* <p>Title: PermissionInterceptor</p>
* <p>Description: 授权拦截器</p>
* @version 1.0
*/
public class PermissionInterceptor implements HandlerInterceptor { //在执行handler之前来执行的
//用于用户认证校验、用户权限校验
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception { //得到请求的url
String url = request.getRequestURI(); //判断是否是公开 地址
//实际开发中需要公开 地址配置在配置文件中 //1.从配置中取逆名访问url
List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
//遍历公开 地址,如果是公开 地址则放行
for(String open_url:open_urls){
if(url.indexOf(open_url)>=0){
//如果是公开 地址则放行
return true;
}
} //2.从配置文件中获取公共访问地址
List<String> common_urls = ResourcesUtil.gekeyList("commonURL");
//遍历公用 地址,如果是公用 地址则放行
for(String common_url:common_urls){
if(url.indexOf(common_url)>=0){
//如果是公开 地址则放行
return true;
}
} //3.获取session
HttpSession session = request.getSession();
ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
//从session中取权限范围的url
List<SysPermission> permissions = activeUser.getPermissions();
for(SysPermission sysPermission:permissions){
//权限的url
String permission_url = sysPermission.getUrl();
if(url.indexOf(permission_url)>=0){
//如果是权限的url 地址则放行
return true;
}
} //4.执行到这里拦截,跳转到无权访问的提示页面
request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(request, response); //如果返回false表示拦截不继续执行handler,如果返回true表示放行
return false;
}
//在执行handler返回modelAndView之前来执行
//如果需要向页面提供一些公用 的数据或配置一些视图信息,使用此方法实现 从modelAndView入手
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("HandlerInterceptor1...postHandle"); }
//执行handler之后执行此方法
//作系统 统一异常处理,进行方法执行性能监控,在preHandle中设置一个时间点,在afterCompletion设置一个时间,两个时间点的差就是执行时长
//实现 系统 统一日志记录
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("HandlerInterceptor1...afterCompletion");
} }

3.7、配置授权拦截器

注意:将授权拦截器配置在用户认证拦截的下边。

    <!--拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 用户认证拦截 -->
<mvc:mapping path="/**" />
<bean class="com.lhx.ssm.controller.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 授权拦截 -->
<mvc:mapping path="/**" />
<bean class="com.lhx.ssm.controller.interceptor.PermissionInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

四、小结

  使用基于url拦截的权限管理方式,实现起来比较简单,不依赖框架,使用web提供filter就可以实现。

问题:

  需要将所有的url全部配置起来,有些繁琐,不易维护,url(资源)和权限表示方式不规范。

  如果漏配置,就会无权访问。

  URL也是一种资源

003-基于URL的权限管理[不使用shiro]的更多相关文章

  1. 基于url的权限管理

    基于url权限管理流程 完成权限管理的数据模型创建. 1.     系统登陆 系统 登陆相当 于用户身份认证,用户成功,要在session中记录用户的身份信息. 操作流程: 用户进行登陆页面 输入用户 ...

  2. shiro-5基于url的权限管理

    1.1 搭建环境 1.1.1 数据库 mysql5.1数据库中创建表:用户表.角色表.权限表(实质上是权限和资源的结合 ).用户角色表.角色权限表. 完成权限管理的数据模型创建. 1.1.2 开发环境 ...

  3. 基于URL的权限管理(三)

    思路:先创建一个专门的类ActiveUser用于存储用户登录的信息,主要用于存储用户id,账户,名称,菜单,权限. 认证拦截器主要是查看用户是否已登陆,如果没有转发到登陆界面,用户用账户跟密码登录时候 ...

  4. 【shiro】(2)---基于RUL的权限管理

    基于RUL的权限管理 我想在写shiro权限管理认证前,先来一个基于URL实现的权限管理控制. 一.基于URI的权限业务逻辑  实现思路:       将系统操作的每个url配置在权限表中,将权限对应 ...

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

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

  6. 在ASP.NET MVC中实现基于URL的权限控制

    本示例演示了在ASP.NET MVC中进行基于URL的权限控制,由于是基于URL进行控制的,所以只能精确到页.这种权限控制的优点是可以在已有的项目上改动极少的代码来增加权限控制功能,和项目本身的耦合度 ...

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

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

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

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

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

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

随机推荐

  1. 陷阱:C++模块之间的”直接依赖“和”间接依赖“与Makefile的撰写

    参考:http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ 参考:http://stackoverflow ...

  2. Mysql下Union注入Bypass安全狗过程

    文章转载于:http://www.0aa.me/index.php/archives/95/ 一次众测发现个注入,然后有安全狗就顺带看了下安全狗. 先fuzz看看安全狗拦截什么关键词union sel ...

  3. Ehcache2 的配置(不使用配置文件)

    EhCache是一个开放源码的,基于标准的高速缓存系统. 网上关于EhCache的使用配置很多,但是一般是基于配置文件的.但是实际应用中.我们可能需要动态的管理缓存,这时候单纯配置文件就不够用了. 所 ...

  4. MFC编程之创建Ribbon样式的应用程序框架

    Ribbon界面就是微软从Office2007開始引入的一种为了使应用程序的功能更加易于发现和使用.降低了点击鼠标的次数的新型界面.从实际效果来看,不仅外观美丽,并且功能直观,用户操作简洁方便. 利用 ...

  5. 【JMeter性能测试】之学习资料总结(持续更新)

    本人测试小白,总结一下JMeter性能测试相关文档进行转载学习,下面会贴出原文作者以示感谢: JMeter性能测试学习地址:http://www.ltesting.net/ceshi/open/kyx ...

  6. 第一百四十二节,JavaScript,封装库--运动动画和透明度动画

    JavaScript,封装库--运动动画和透明度动画 /** yi_dong_tou_ming()方法,说明 * * yi_dong_tou_ming()方法,将一个元素,进行一下动画操作 * 1,x ...

  7. python 糗事百科实例

    爬取糗事百科段子,假设页面的URL是 http://www.qiushibaike.com/8hr/page/1 要求: 使用requests获取页面信息,用XPath / re 做数据提取 获取每个 ...

  8. python import错误 SyntaxError: invalid syntax

    导入一个叫service-listener.py的文件是一直遇到错误: SyntaxError: invalid syntax 单独运行service-listener这个文件时,没有问题,只是不能被 ...

  9. (转)java synchronised关键字

    转自:http://www.cnblogs.com/mengdd/archive/2013/02/16/2913806.html Java 多线程(六) synchronized关键字详解 Java ...

  10. 手动编译svn

    #!/bin/bash yum -y remove subversionmkdir -p /dist/{dist,src}cd /dist/dist/bin/rm -f openssl* subver ...