权限控制方案之——基于URL拦截
2017-03-28 10:19
190 查看
概述:
在系统开发过程中需要考虑的一个重要的问题就是权限问题,权限问题也是安全问题的一个范畴,我们要求在用户登录系统之后,要控制用户可以访问的系统资源,使得用户只可以访问到系统事先分配好的资源;这里的资源可以是一个URL地址,也可以是页面上的菜单和按钮等。对于实现权限的控制有多种方案,这里说明一下通过URL拦截的方式进行权限控制的实现方案。基本流程:
对于权限的控制可以分为两个步骤:认证和授权。认证:即用户登录系统的时候对用户的身份信息进行判别。
授权:即在用户登录成功后为用户分配用户可以访问的资源。
流程图:根据用户的认证和授权过程抽象出如下流程图
通用模型:
根据我们对权限控制的要求,我们可以抽取出如下数据模型:主体:用户,程序等,包括账号和密码等属性
资源:URL,菜单,按钮等
角色:为了方便资源和主体之间的关系管理,我们一般会在它们之间抽取出一个角色实体,一个角色就是一类主体,通过角色可以实现对主体的分组管理,这样可以更加方便的对主体和其所对应的资源进行管理(扩张和修改)。
模型结构如下图所示:
实现过程:
1、定义用户身份和基本操作:
这里我们创建一个用户的身份实体ActiveUser,用来存放用户的身份信息,在用户登录成功后将该身份信息存放到session当中,//用户登陆请求
@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";
}
//退出请求
@RequestMapping("/logout")
public String logout(HttpSession httpSession) throws Exception{
//清空session
httpSession.invalidate();
return "redirect:first.action";
}
2、公开访问地址配置:
对于不需要用户认证就可以访问的地址信息进行配置,这里我们可以单独写一个配置文件进行配置,后边读取判断。#公开访问地址
login.action=登录页面
loginsubmit.action=登录请求
3、公共访问地址配置:
对于只要用户认证通过就可以访问的地址信息进行配置,这里我们同样也是通过一个配置文件进行配置,后边通过读取判断。#公共访问地址
first.action=首页
logout.action=退出
4、认证拦截器:
通过认证拦截器对用户身份信息进行判断。public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// 校验是否是公开资源地址
List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
// 用户访问的url
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;
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
}
5、授权拦截器
通过授权拦截器,判断用户是否具有访问资源的权限。public class PermissionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String url = request.getRequestURI();
// 校验是否是公开资源地址
List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
for (String open_url : open_urls) {
if (url.indexOf(open_url) >= 0) {
// 公开地址放行
return true;
}
}
//判断是否是公共访问地址
List<String> common_urls = ResourcesUtil.gekeyList("commonURL");
for (String common_url : common_urls) {
if (url.indexOf(common_url) >= 0) {
//公共地址放行
return true;
}
}
HttpSession session = request.getSession();
ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
// 获取用户权限列表
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;
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
}
6、配置拦截器
将拦截器配置起来,使其工作。<!-- 拦截器 -->
<mvc:interceptors>
<!-- 多个拦截器,顺序执行 -->
<!-- 认证拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="cn.itcast.ssm.controller.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
<!-- 授权拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="cn.itcast.ssm.controller.interceptor.PermissionInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
总结
这里主要是通过两个拦截器实现了认证和授权,其优点是可以不必依赖于框架实现,对于拦截器我们也可以通过web提供的filter实现;缺点在于对于系统配置很多的URL,或者在系统初始化时将URL设置到数据库中,再有就是对于访问地址的变动要同时改变配置,维护相对不易。
相关文章推荐
- 权限控制方案之——基于URL拦截
- 尝试asp.net mvc 基于controller action 方式权限控制方案可行性
- 一种基于delphi巧妙权限控制方案及其实现方法
- 基于url拦截实现权限控制
- 详解基于vue-router的动态权限控制实现方案
- 基于vue用户权限控制的方案
- 一种简单方便的权限控制方案
- 基于资源控制的权限管理想法
- AspNetForums中基于角色的权限控制
- AspNetForums中基于角色的权限控制
- 基于Samba的Windows Linux 文件共享方法(无权限控制)
- 基于角色访问的权限控制
- 如何设计数据库表实现完整的RBAC(基于角色权限控制)
- AspNetForums中基于角色的权限控制
- MOSS字段编辑权限控制方案(2)-添加管理链接
- MOSS字段编辑权限控制方案(3)-重写表单字段呈现逻辑
- 基于角色-功能-资源的权限控制模型的设计与实现-引子
- 基于角色的权限控制
- 基于角色的权限控制
- 面试题 简单基于角色控制的权限管理系统