Shiro(五):Shiro 授权

17 篇文章 2 订阅

Shiro(四)介绍Shiro 多Realm验证和认证策略,接下来讲解Shiro 授权。

一、权限配置

1.基本概念

  • 授权,也叫访问控制,即在应用中控制谁访问哪些资源(如访问页面/编辑数据/页面操作 等)。

在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限(Permission)、角色(Role)。

  • 主体(Subject)访问应用的用户,在 Shiro 中使用 Subject 代表该用户。用户只有授权后才允许访问相应的资源。

  • 资源(Resource)在应用中用户可以访问的 URL,比如访问 JSP 页面、查看/编辑某些数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问。

  • 权限(Permission):安全策略中的原子授权单位,通过权限我们可以表示在应用中用户有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源,如:访问用户列表页面查看/新增/修改/删除用户数据(即很多时候都是CRUD(增查改删)式权限控制)等。权限代表了用户有没有操作某个资源的权利,即反映在某个资源上的操作允不允许。

  • Shiro 支持粗粒度权限(如用户模块的所有权限)和细粒度权限(操作某个用户的权限,即实例级别的)

  • 角色(Role)权限的集合一般情况下会赋予用户角色而不是权限,即这样用户可以拥有一组权限,赋予权限时比较方便。典型的如:项目经理、技术总监、CTO、开发工程师等都是角色,不同的角色拥有一组不同的权限。

2.Shiro 授权方式

Shiro 支持三种方式的授权:
(1)编程式:通过写if/else 授权代码块完成(不常用) :

if(subject.hasRole("admin")){
   //有权限
}else{
   //无权限
}

(2)注解式:通过在执行的Java方法上放置相应的注解完成,没有权限将抛出相应的异常常用

@RequiresRoles("admin")
public void hello(){
  //有权限
}

(3)JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成

<shiro:hasRole name="admin">
   <!--有权限-->
</shiro:hasRole>

通过标签可以隐藏没有权限访问的资源

注意:注解式 是常用的方式

3.默认拦截器

Shiro 内置了很多默认的拦截器,比如身份验证、授权等相关的。默认拦截器可以参考org.apache.shiro.web.filter.mgt.DefaultFilter中的枚举
1)默认拦截器:
在这里插入图片描述
2)详细区分
①身份验证相关的(5个)
在这里插入图片描述
②授权相关的(5个)
在这里插入图片描述
③其他(1个)
在这里插入图片描述

4.Permissions

在这里插入图片描述
Shiro 的 Permissions:

5.授权 roles 的配置使用

新建两个jsp页面:admin.jsp和user.jsp,希望实现访问admin.jsp,需要具备admin的权限,访问user.jsp,需要具备user的权限

步骤:
(1)新建两个jsp页面:admin.jsp和user.jsp
admin.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
  <h3>Admin Page</h3>
</body>
</html>

user.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
  <h3>User Page</h3>
</body>
</html>

(2)在list.jsp页面添加访问admin.jsp 和 user.jsp的超链接:

controller:

	/**
	 * 进入admin页面
	 * @return
	 */
	@RequestMapping("/toAdmin")
	public ModelAndView admin(){
		return new ModelAndView("admin");
	}
	
	/**
	 * 进入user页面
	 * @return
	 */
	@RequestMapping("/toUser")
	public ModelAndView user(){
		return new ModelAndView("user");
	}

list.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>list</title>
</head>
<body>
  
  <h3>list Page</h3>
  <div>欢迎登录</div>
  
  <a href="toAdmin">Admin page</a><br>
  <a href="toUser">User page</a><br>
  <a href="logout">logout</a>
</body>
</html>

(3)权限配置:在applicationContext.xml文件中 添加 上面两个访问链接的角色过滤
在这里插入图片描述
(4)启动项目服务,进行测试:
输入用户名admin,密码123456,点击submit,登录成功,进入list页面,由于上面配置 admin.jsp、user.jsp页面的访问需要 admin 、user角色权限,所以是没有权限访问,会进入unauthorized.jsp页面。user用户登录访问是一样的效果。
在这里插入图片描述

二、Shiro 实现授权

1.授权流程

在这里插入图片描述
流程如下:

  • 1、首先调用 Subject.isPermitted*/hasRole* 接口,其会委托给SecurityManager,而SecurityManager 接着会委托给 Authorizer;
  • 2、Authorizer是真正的授权者,如果调用如isPermitted(“user:view”),其首先会通过
    PermissionResolver 把字符串转换成相应的 Permission 实例;
  • 3、在进行授权之前,其会调用相应的 Realm 获取 Subject 相应的角色/权限用于匹配传入的角色/权限;
  • 4、Authorizer 会判断 Realm 的角色/权限是否和传入的匹配,如果有多个Realm,会委托给 ModularRealmAuthorizer 进行循环判断,如果匹配如 isPermitted*/hasRole* 会返回true,否则返回false表示授权失败。

授权的Realm如何实现?
答:授权需要继承 AuthorizingRealm类,并实现其doGetAuthorizationInfo方法。

注意点:AuthorizingRealm类继承自AuthenticatingRealm,但没有实现AuthenticatingRealm中的doGetAuthenticationInfo方法,所以认证和授权只需要继承AuthorizingRealm就可以了,同时需要实现它的两个抽象方法。

2.实现

ModularRealmAuthorizer 进行多 Realm 匹配流程

  • 1、首先检查相应的 Realm 是否实现了实现了Authorizer;
  • 2、如果实现了 Authorizer,那么接着调用其相应的isPermitted*/hasRole* 接口进行匹配;
  • 3、如果有一个Realm匹配那么将返回 true,否则返回 false。

多Realm授权的通过标准:

查看源码:
在这里插入图片描述
可以看到 只要有一个授权通过,它就可以进行 return true.

结论:多个Realm授权,只要有一个通过就可以。

2.1 修改 ShiroRealm.java

(1)修改 ShiroRealm的继承类,并实现doGetAuthorizationInfo方法

在这里插入图片描述
在这里插入图片描述
(2)doGetAuthorizationInfo方法实现

 /**
     * 授权
     * 授权会被shiro回调的方法
     */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		System.out.println("doGetAuthorizationInfo---");
		//1. 从 PrincipalCollection 中来获取登录用户的信息
		Object principal = principals.getPrimaryPrincipal();
		//2. 利用登录用户的信息来获取当前用户的角色或权限(可能需要查询数据库)
		Set<String> roles= new HashSet<String>();
		roles.add("user");//每个用户都有user这个角色
		if("admin".equals(principal)){
			roles.add("admin");//admin用户还有admin角色
		}
		//3. 创建 SimpleAuthorizationInfo,并设置其 roles 属性
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roles);
		//4. 返回 SimpleAuthorizationInfo 对象
		return simpleAuthorizationInfo;
	}

2.2 测试

(1)admin用户登录,admin.jsp和 user.jsp 两个页面都可以访问:
在这里插入图片描述

(2)user用户登录,user.jsp 页面可以访问,而admin.jsp页面没有权限访问 :

在这里插入图片描述
测试成功

可点击此处获取源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值