权限控制方案之——基于URL拦截
概述:
在系统开发过程中需要考虑的一个重要的问题就是权限问题,权限问题也是安全问题的一个范畴,我们要求在用户登录系统之后,要控制用户可以访问的系统资源,使得用户只可以访问到系统事先分配好的资源;这里的资源可以是一个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拦截的更多相关文章
- 基于url拦截实现权限控制
用户表,角色表,用户角色表,权限表,权限角色表 1.用户通过认证(可以是验证用户名,密码等) 2.登陆拦截器,为公开的url放行, 登陆时,将用户信息放入session中,获得用户的权限集合,将集合放 ...
- 尝试asp.net mvc 基于controller action 方式权限控制方案可行性
微软在推出mvc框架不久,短短几年里,版本更新之快,真是大快人心,微软在这种优秀的框架上做了大量的精力投入,是值得赞同的,毕竟程序员驾驭在这种框架上,能够强力的精化代码,代码层次也更加优雅,扩展较为方 ...
- 尝试asp.net mvc 基于controller action 方式权限控制方案可行性(转载)
微软在推出mvc框架不久,短短几年里,版本更新之快,真是大快人心,微软在这种优秀的框架上做了大量的精力投入,是值得赞同的,毕竟程序员驾驭在这种框架上,能够强力的精化代码,代码层次也更加优雅,扩展较为方 ...
- python RBAC权限控制模型扩展 基于JWT实现
jwt,全称 json web token,是使用一定的加密规则生成的token串来保证登录状态.验证用户身份.做权限认证等工作 以往保存用户登录状态多用session实现,但是当服务涉及多台服务器分 ...
- PHP中多IP段权限控制方案
在某些项目中我们可能会用到根据IP段进行权限校验,比如不在我们配置的IP段内的用户访问某些页面或功能模块时,将提示其权限不够并禁止访问该页面的内容.鉴于项目中需求各异,下面只说下大致思路以及我个人的实 ...
- 基于url拦截
- 项目一:第十二天 1、常见权限控制方式 2、基于shiro提供url拦截方式验证权限 3、在realm中授权 5、总结验证权限方式(四种) 6、用户注销7、基于treegrid实现菜单展示
1 课程计划 1. 常见权限控制方式 2. 基于shiro提供url拦截方式验证权限 3. 在realm中授权 4. 基于shiro提供注解方式验证权限 5. 总结验证权限方式(四种) 6. 用户注销 ...
- JAVAEE——BOS物流项目10:权限概述、常见的权限控制方式、apache shiro框架简介、基于shiro框架进行认证操作
1 学习计划 1.演示权限demo 2.权限概述 n 认证 n 授权 3.常见的权限控制方式 n url拦截权限控制 n 方法注解权限控制 4.创建权限数据模型 n 权限表 n 角色表 n 用户表 n ...
- 基于URL权限拦截的实现
一.实现原理 1.实现原理 本示例采用SpringMVC的拦截器来实现一个基于URL的权限拦截. 2.权限管理流程 二.数据库搭建 1.用户表(sys_user) (1)表结构 (2)表字段说明 ...
随机推荐
- ORACLE RMAN备份及还原 RMAN能够进行增量备份:数据库,表空间,数据文件
ORACLE RMAN备份及还原 RMAN能够进行增量备份:数据库.表空间.数据文件 仅仅有使用过的block能够被备份成backup set 表空间与数据文件相应关系:dba_data_file ...
- 使用maven进行测试设置断点调试的方法
在Maven中配置测试插件surefire来进行单元测试,默认情况下,surefire会执行文件名以Test开头或结尾的测试用例,或者是以TestCase结尾的测试用例. ...
- NoSql中的B-tree、B+tree和LSM-tree 分类: B7_HBASE 2015-03-15 18:27 85人阅读 评论(0) 收藏
总结: 1.B+树将数据完全排序,读数据时很快,但当要修改数据时,就需要将新入数据下面的数据重新排位,特别是当写入的数据排在较高的位置时,需要大量的移位操作才能完成写入. 2.SLM牺牲部分的读性能, ...
- js如何生成[n,m]的随机数
js如何生成[n,m]的随机数 一.总结 一句话总结:生成随机数就是用的Math的random方法. 1.Math.random()得到的数据的左右开闭情况是怎样的? 左闭又开 所以Math.floo ...
- [Elm] Functions in Elm
Functions are an important building block in Elm. In this lesson we will review stateless functions, ...
- Oracle 字符集的查看和修改 分类: H2_ORACLE 2013-06-19 16:52 316人阅读 评论(0) 收藏
一.什么是Oracle字符集 Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系.ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据.它使数据库 ...
- sequence配置
在实现分库分表的情况下,数据库自增主键已经无法保证在集群中是全局唯一的主键了,因此mycat提供了全局的sequence,并且提供了本地配置.数据库配置等多种实现方式. 本地文件方式 采用该方式,my ...
- 百度地图坐标之间的距离php
function GetDistance($lat1, $lng1, $lat2, $lng2){ define('PI',3.1415926535898); define('EARTH_RADIUS ...
- 【45.65%】【codeforces 560B】Gerald is into Art
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- PatentTips - Sprite Graphics Rendering System
BACKGROUND This disclosure relates generally to the field of computer graphics. More particularly, b ...