003-基于URL的权限管理[不使用shiro]
一、基于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]的更多相关文章
- 基于url的权限管理
基于url权限管理流程 完成权限管理的数据模型创建. 1. 系统登陆 系统 登陆相当 于用户身份认证,用户成功,要在session中记录用户的身份信息. 操作流程: 用户进行登陆页面 输入用户 ...
- shiro-5基于url的权限管理
1.1 搭建环境 1.1.1 数据库 mysql5.1数据库中创建表:用户表.角色表.权限表(实质上是权限和资源的结合 ).用户角色表.角色权限表. 完成权限管理的数据模型创建. 1.1.2 开发环境 ...
- 基于URL的权限管理(三)
思路:先创建一个专门的类ActiveUser用于存储用户登录的信息,主要用于存储用户id,账户,名称,菜单,权限. 认证拦截器主要是查看用户是否已登陆,如果没有转发到登陆界面,用户用账户跟密码登录时候 ...
- 【shiro】(2)---基于RUL的权限管理
基于RUL的权限管理 我想在写shiro权限管理认证前,先来一个基于URL实现的权限管理控制. 一.基于URI的权限业务逻辑 实现思路: 将系统操作的每个url配置在权限表中,将权限对应 ...
- 基于DDDLite的权限管理OpenAuth.net 1.0版正式发布
距离上一篇OpenAuth.net的文章已经有5个多月了,在这段时间里项目得到了很多朋友的认可,开源中国上面的Star数接近300,于是坚定了我做下去的信心.最近稍微清闲点,正式推出1.0版,并在阿里 ...
- 在ASP.NET MVC中实现基于URL的权限控制
本示例演示了在ASP.NET MVC中进行基于URL的权限控制,由于是基于URL进行控制的,所以只能精确到页.这种权限控制的优点是可以在已有的项目上改动极少的代码来增加权限控制功能,和项目本身的耦合度 ...
- 10.spring-boot基于角色的权限管理页面实现
10.spring-boot基于角色的权限管理页面实现
- 基于云端的通用权限管理系统,SAAS服务,基于SAAS的权限管理,基于SAAS的单点登录SSO,企业单点登录,企业系统监控,企业授权认证中心
基于云端的通用权限管理系统 SAAS服务 基于SAAS的权限管理 基于SAAS的单点登录SSO 基于.Net的SSO,单点登录系统,提供SAAS服务 基于Extjs 4.2 的企业信息管理系统 基于E ...
- devops-jenkins基于角色的权限管理RBAC
一. devops-jenkins基于角色的权限管理RBAC 1 安装角色的rbac角色管理 1.1) 点击系统管理 1.2) 选择插件管理 1.3) 选择可选插件,输入role搜索 1.4) 选择 ...
随机推荐
- IntelliJ IDEA代码编码区提示库源不匹配字节码解决办法
在使用IntelliJ IDEA进行开发时,可能会在代码编辑区出现此提示:library source does not match the bytecode for class HelloWorld ...
- mysql循环查询
begin declare i int;set i = 1;lp1 : LOOPSELECT insert(t.bb,4,6,'XXXX') FROM t_aa t; set i = i+1; if ...
- What is Web Application Architecture? How It Works, Trends, Best Practices and More
At Stackify, we understand the amount of effort that goes into creating great applications. That’s w ...
- Github上fork项目后与原项目保持同步
**步骤** 假设来源为 `https://github.com/_original/_project.git` fork 项目为 `https://github.com/_your/_projec ...
- 分析并实现 360 P1路由器上的测速功能(也可以针对金山测速功能)
现在各种智能路由器以及一些PC上的防火墙软件,都提供网络测速功能.笔者对此进行了研究,并在自己的路由器上也实现了此功能.下面做一下总结 一般的网络测速,主要关注两个方面:网络延迟和下载速率 1.网络延 ...
- java.lang.NoSuchMethodError: org.apache.spark.util.ThreadUtils$.newDae
-classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1. ...
- Nexus 5 刷机 - Android 5.0 Lollipop
Nexus刷机 : 官方地址 刷机步骤 下载相应的安装包 连接USB 重启手机,进入BootLoader界面 : 使用命令 adb reboot bootloader 关机; 音量键下 + 电源键 ...
- Iptables规则执行顺序详解
1.The first is the mangle table which is responsible for the alteration of quality of service bits ...
- 图片触及翻转效果 css3
实现图片由左向右飞入回到最初设定位置 ,鼠标浮上去旋转显示另一张图片效果: html: <!DOCTYPE HTML> <html> <head> <meta ...
- MFC多国语言——资源副本
此随笔主要参考了http://www.cnblogs.com/xianyunhe/archive/2011/09/02/2163842.html 为软件提供多国语言的支持的具体实现方法有很多,但基本原 ...