shiro教程(1)-基于url权限管理

shiro教程系列

shiro教程(2)

shiro教程(3)

shiro教程(4)

一、 权限管理

1.1 什么是权限管理

基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。

权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。

1.2 用户身份认证

1.2.1 概念

身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡。

1.2.2 用户名密码身份认证流程

1.2.3 关键对象

上边的流程图中需要理解以下关键对象:

Subject:主体

访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体;

Principal:身份信息

是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(PrimaryPrincipal)。

credential:凭证信息

是只有主体自己知道的安全信息,如密码、证书等。

1.3 授权

1.3.1 概念

授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。

1.3.2 授权流程

下图中橙色为授权流程。

1.3.3 关键对象

授权可简单理解为who对what(which)进行How操作:

Who,即主体(Subject),主体需要访问系统中的资源。

What,即资源(Resource),如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型和资源实例,比如商品信息为资源类型,类型为t01的商品为资源实例,编号为001的商品信息也属于资源实例。

How,权限/许可(Permission),规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作许可。

权限分为粗颗粒和细颗粒,粗颗粒权限是指对资源类型的权限,细颗粒权限是对资源实例的权限。

主体、资源、权限关系如下图:

1.3.4 权限模型

对上节中的主体、资源、权限通过数据模型表示。

主体(账号、密码)

资源(资源名称、访问地址)

权限(权限名称、资源id)

角色(角色名称)

角色和权限关系(角色id、权限id)

主体和角色关系(主体id、角色id)

如下图:

如下图:

通常企业开发中将资源和权限表合并为一张权限表,如下:

资源(资源名称、访问地址)

权限(权限名称、资源id)

合并为:

权限(权限名称、资源名称、资源访问地址)

上图常被称为权限管理的通用模型,不过企业在开发中根据系统自身的特点还会对上图进行修改,但是用户、角色、权限、用户角色关系、角色权限关系是需要去理解的。

1.3.5 权限分配

对主体分配权限,主体只允许在权限范围内对资源进行操作,比如:对u01用户分配商品修改权限,u01用户只能对商品进行修改。

权限分配的数据通常需要持久化,根据上边的数据模型创建表并将用户的权限信息存储在数据库中。

1.3.6 权限控制

用户拥有了权限即可操作权限范围内的资源,系统不知道主体是否具有访问权限需要对用户的访问进行控制。

1.3.6.1 基于角色的访问控制

RBAC基于角色的访问控制(Role-Based Access Control)是以角色为中心进行访问控制,比如:主体的角色为总经理可以查询企业运营报表,查询员工工资信息等,访问控制流程如下:

上图中的判断逻辑代码可以理解为:

if(主体.hasRole("总经理角色id")){

查询工资

}

缺点:以角色进行访问控制粒度较粗,如果上图中查询工资所需要的角色变化为总经理和部门经理,此时就需要修改判断逻辑为“判断主体的角色是否是总经理或部门经理”,系统可扩展性差。

修改代码如下:

if(主体.hasRole("总经理角色id") ||  主体.hasRole("部门经理角色id")){

查询工资

}

1.3.6.2 基于资源的访问控制

RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制,比如:主体必须具有查询工资权限才可以查询员工工资信息等,访问控制流程如下:

上图中的判断逻辑代码可以理解为:

if(主体.hasPermission("查询工资权限标识")){

查询工资

}

优点:系统设计时定义好查询工资的权限标识,即使查询工资所需要的角色变化为总经理和部门经理也只需要将“查询工资信息权限”添加到“部门经理角色”的权限列表中,判断逻辑不用修改,系统可扩展性强。

权限管理解决方案

2.1 粗颗粒度和细颗粒度

2.1.1 什么是粗颗粒度和细颗粒度

对资源类型的管理称为粗颗粒度权限管理,即只控制到菜单、按钮、方法,粗粒度的例子比如:用户具有用户管理的权限,具有导出订单明细的权限。对资源实例的控制称为细颗粒度权限管理,即控制到数据级别的权限,比如:用户只允许修改本部门的员工信息,用户只允许导出自己创建的订单明细。

2.1.2 如何实现粗颗粒度和细颗粒度

对于粗颗粒度的权限管理可以很容易做系统架构级别的功能,即系统功能操作使用统一的粗颗粒度的权限管理。

对于细颗粒度的权限管理不建议做成系统架构级别的功能,因为对数据级别的控制是系统的业务需求,随着业务需求的变更业务功能变化的可能性很大,建议对数据级别的权限控制在业务层个性化开发,比如:用户只允许修改自己创建的商品信息可以在service接口添加校验实现,service接口需要传入当前操作人的标识,与商品信息创建人标识对比,不一致则不允许修改商品信息。

2.2 基于url拦截

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

如下图:

2.3 使用权限管理框架

对于权限管理基本上每个系统都有,使用权限管理框架完成权限管理功能的开发可以节省系统开发时间,并且权限管理框架提供了完善的认证和授权功能有利于系统扩展维护,但是学习权限管理框架是需要成本的,所以选择一款简单高效的权限管理框架显得非常重要。

基于url拦截实现

3.1 环境准备

jdk:1.7.0_72

web容器:tomcat7

系统框架:springmvc3.2.0+mybatis3.2.7(详细参考springmvc教案)

前台UI:jQuery easyUI1.2.2

3.2 数据库

创建mysql5.1数据库

创建用户表、角色表、权限表、角色权限关系表、用户角色关系表。

导入脚本,先导入shiro_sql_talbe.sql再导入shiro-sql_table_data.sql

3.3 activeUser用户身份类

用户登陆成功记录activeUser信息并将activeUser存入session。

[java] view plain copy print?

  1. public class ActiveUser implements java.io.Serializable {
  2. private String userid;//用户id
  3. private String usercode;// 用户账号
  4. private String username;// 用户名称
  5. private List<SysPermission> menus;// 菜单
  6. private List<SysPermission> permissions;// 权限

3.4 anonymousURL.properties

anonymousURL.properties公开访问地址,无需身份认证即可访问。

3.5 commonURL.properties

commonURL.properties公共访问地址,身份认证通过无需分配权限即可访问。

3.6 用户身份认证拦截器

使用springmvc拦截器对用户身份认证进行拦截,如果用户没有登陆则跳转到登陆页面,本功能也可以使用filter实现 。

[java] view plain copy print?

  1. public class LoginInterceptor implements HandlerInterceptor {
  2. // 在进入controller方法之前执行
  3. // 使用场景:比如身份认证校验拦截,用户权限拦截,如果拦截不放行,controller方法不再执行
  4. @Override
  5. public boolean preHandle(HttpServletRequest request,
  6. HttpServletResponse response, Object handler) throws Exception {
  7. // 校验用户访问是否是公开资源地址(无需认证即可访问)
  8. List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
  9. // 用户访问的url
  10. String url = request.getRequestURI();
  11. for (String open_url : open_urls) {
  12. if (url.indexOf(open_url) >= 0) {
  13. // 如果访问的是公开 地址则放行
  14. return true;
  15. }
  16. }
  17. // 校验用户身份是否认证通过
  18. HttpSession session = request.getSession();
  19. ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
  20. if (activeUser != null) {
  21. // 用户已经登陆认证,放行
  22. return true;
  23. }
  24. // 跳转到登陆页面
  25. request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,
  26. response);
  27. return false;
  28. }

3.7 用户授权拦截器

使用springmvc拦截器对用户访问url进行拦截,如果用户访问的url没有分配权限则跳转到无权操作提示页面(refuse.jsp),本功能也可以使用filter实现。

[java] view plain copy print?

  1. public class PermissionInterceptor implements HandlerInterceptor {
  2. // 在进入controller方法之前执行
  3. // 使用场景:比如身份认证校验拦截,用户权限拦截,如果拦截不放行,controller方法不再执行
  4. // 进入action方法前要执行
  5. @Override
  6. public boolean preHandle(HttpServletRequest request,
  7. HttpServletResponse response, Object handler) throws Exception {
  8. // TODO Auto-generated method stub
  9. // 用户访问地址:
  10. String url = request.getRequestURI();
  11. // 校验用户访问是否是公开资源地址(无需认证即可访问)
  12. List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
  13. // 用户访问的url
  14. for (String open_url : open_urls) {
  15. if (url.indexOf(open_url) >= 0) {
  16. // 如果访问的是公开 地址则放行
  17. return true;
  18. }
  19. }
  20. //从 session获取用户公共访问地址(认证通过无需分配权限即可访问)
  21. List<String> common_urls = ResourcesUtil.gekeyList("commonURL");
  22. // 用户访问的url
  23. for (String common_url : common_urls) {
  24. if (url.indexOf(common_url) >= 0) {
  25. // 如果访问的是公共地址则放行
  26. return true;
  27. }
  28. }
  29. // 从session获取用户权限信息
  30. HttpSession session = request.getSession();
  31. ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
  32. // 取出session中权限url
  33. // 获取用户操作权限
  34. List<SysPermission> permission_list = activeUser.getPermissions();
  35. // 校验用户访问地址是否在用户权限范围内
  36. for (SysPermission sysPermission : permission_list) {
  37. String permission_url = sysPermission.getUrl();
  38. if (url.contains(permission_url)) {
  39. return true;
  40. }
  41. }
  42. // 跳转到页面
  43. request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(
  44. request, response);
  45. return false;
  46. }

3.8 用户登陆

用户输入用户账号和密码登陆,登陆成功将用户的身份信息(用户账号、密码、权限菜单、权限url等)记入activeUser类,并写入session。

3.8.1 controller

[java] view plain copy print?

  1. //用户登陆提交
  2. @RequestMapping("/loginsubmit")
  3. public String loginsubmit(HttpSession session,String usercode,String password,String randomcode) throws Exception{
  4. //校验验证码
  5. //从session获取正确的验证码
  6. String validateCode = (String)session.getAttribute("validateCode");
  7. if(!randomcode.equals(validateCode)){
  8. //抛出异常:验证码错误
  9. throw new CustomException("验证码 错误 !");
  10. }
  11. //用户身份认证
  12. ActiveUser activeUser = sysService.authenticat(usercode, password);
  13. //记录session
  14. session.setAttribute("activeUser", activeUser);
  15. return "redirect:first.action";
  16. }

3.8.2 service接口

[java] view plain copy print?

  1. /**
  2. *
  3. * <p>
  4. * Title: authenticat
  5. * </p>
  6. * <p>
  7. * Description:用户认证
  8. * </p>
  9. *
  10. * @param usercode
  11. *            用户账号
  12. * @param password
  13. *            用户密码
  14. * @return ActiveUser 用户身份信息
  15. * @throws Exception
  16. */
  17. public ActiveUser authenticat(String usercode, String password)
  18. throws Exception;
  19. // 根据账号查询用户
  20. public SysUser findSysuserByUsercode(String usercode) throws Exception;
  21. // 根据用户id获取权限
  22. public List<SysPermission> findSysPermissionList(String userid)
  23. throws Exception;
  24. // 根据用户id获取菜单
  25. public List<SysPermission> findMenuList(String userid) throws Exception;
时间: 2024-10-18 12:54:32

shiro教程(1)-基于url权限管理的相关文章

【基于url权限管理 shiro(一)】--基础

只要有用户参与的系统一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源.权限管理包括用户认证和授权两部分.   用户认证 1.概念 用户认证,用户去访问系统,系统要验证用户身份的合法性.最常用的用户身份验证的方法:1.用户名密码方式.2.指纹打卡机.3.基于证书验证方法..系统验证用户身份合法,用户方可访问系统的资源. 2.用户认证流程   3.关键对象 subject:主体,理解为用户,可能是程序,都要去访问系统的资源,系

基于RBAC权限管理模型学习

在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权限的管理. 在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色.角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收. 角色与角色的关系可以建立起来以囊括更广泛的客观情况. BAC支持三个著名的安全原则:最小权限原则,责任分离原则和数据抽象原则. (1)最小权限原则之所以被RBAC所支持,是因

基于RBAC权限管理

一般web系统操作人员多时都会需求权限管理,一来限制操作范围,二来限制数据公开度. 现在最流行的一个模式为 RBAC (Role-Based Access Control) 基于角色的访问控制.设定权限范围定义到角色中,然后再分配到每个用户. 这里仅以一般后台管理系统为例,叙说数据结构: 需求: 菜单需要针对不同部门使用不同的菜单结构. 权限项能精确到页面中某个内容或局部功能. 基本要求:没有权限的菜单,页面中内容或链接禁止显示. 表结构 CREATE TABLE `power_item` (

Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理

本文是接着上篇博客写的:Spring boot 入门(三):SpringBoot 集成结合 AdminLTE(Freemarker),利用 generate 自动生成代码,利用 DataTable 和 PageHelper 进行分页显示.按照前面的博客,已经可以搭建一个简单的 Spring Boot 系统,本篇博客继续对此系统进行改造,主要集成了 Shiro 权限认证框架,关于 Shiro 部分,在本人之前的博客(认证与Shiro安全框架)有介绍到,这里就不做累赘的介绍. 此系列的博客为实践部分

003-基于URL的权限管理[没有结合shiro]

一.基于url权限管理流程 基于url拦截是企业中常用的权限管理方法,实现思路是:将系统操作的每个url配置在权限表中,将权限对应到角色,将角色分配给用户,用户访问系统功能通过Filter进行过虑,过虑器获取到用户访问的url,只要访问的url是用户分配角色中的url则放行继续访问. 二.环境搭建以及核心代码 https://github.com/bjlhx15/shiro/tree/master/permission_url 1.数据库 2.开发环境 3.系统工程框架 4.系统登录 5.用户认

Shiro学习(19)动态URL权限限制

用过Spring Security的朋友应该比较熟悉对URL进行全局的权限控制,即访问URL时进行权限匹配:如果没有权限直接跳到相应的错误页面.Shiro也支持类似的机制,不过需要稍微改造下来满足实际需求.不过在Shiro中,更多的是通过AOP进行分散的权限控制,即方法级别的:而通过URL进行权限控制是一种集中的权限控制.本章将介绍如何在Shiro中完成动态URL权限控制. 本章代码基于<第十六章 综合实例>,请先了解相关数据模型及基本流程后再学习本章. 表及数据SQL 请运行shiro-ex

【转载】JavaEE权限管理分析

JavaEE权限管理分析 一.背景        在 Web 应用开发中,安全一直是非常重要的一个方面.安全虽然属于应用的非功能性需求,但是应该在应用开发的初期就考虑进来.如果在应用开发的后期才考虑安全的问题,就可能陷入一个两难的境地:一方面,应用存在严重的安全漏洞,无法满足用户的要求,并可能造成用户的隐私数据被攻击者窃取:另一方面,应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的调整,因而需要更多的开发时间,影响应用的发布进程.因此,从应用开发的第一天就应该把安全相关

[Shiro] - 基于URL配置动态权限

基于shiro进阶 更改了数据库表 之前的PageController是通过@RequiresPermissions和@RequiresRoles进行是否有权限/是否有角色的判定调用@RequestMapping路径 在PermissionService中加入了两个方法:needInterceptor, listPermissionURLs needInterceptor表示是否要进行拦截,判断依据是如果访问的某个url,在权限系统里存在,就要进行拦截. 如果不存在就放行了. 这一种策略,也可以

Springmvc集成Shiro实现权限管理

Shiro是一个安全框架,他可以集成其他开发开发框架 如:Springmvc,实现用户身份认证.权限管理等等功能,shiro详细的介绍也就不讲了,这里给出一些关键的知识点吧: 知识点: shiro中默认的过滤器 过滤器名称 过滤器类 描述 anon org.apache.shiro.web.filter.authc.AnonymousFilter 匿名过滤器 authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter 如果继续