Shiro学习笔记(四)——shiro实现授权

授权概述

授权,也叫访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等)。
在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限(Permission)、 角色(Role)

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

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

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

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

授权流程

在这里插入图片描述分四步:

  1. Subject 发起请求,判断是否具有相应的角色或权限

  2. SecurityManager 委托给Authorizer

  3. Authorizer 授权器

  4. Realm 查找角色和权限信息

授权

[users]
# 用户zhang的密码是zs,此用户具有role1和role2两个角色
zhangsan = zs, role1, role2
# 用户wang的密码是123,此用户具有role2角色
wang = 123, role2

# 权限
[roles]
# 角色role1对资源user拥有create、update权限
role1 = user:create, user:update
# 角色role2对资源user拥有create、delete权限
role2 = user:create, user:delete
# 角色role3对资源user拥有create权限
role3 = user:create

权限配置规则

角色权限的配置规则: 角色=权限1,权限2

权限标识符号规则:== 资源标识符:操作:实例id==

user:create:01 表示拥有对user资源的01实例进行create操作的权限。

user:create:* 表示拥有对user资源进行create操作的权限,对所有用户资源实例进行create操作。 简写:user:update

user:* : * 表示拥有user资源的所有操作权限。简写 user 或 user:*(推荐)

*:insert: * 表示拥有对所有资源插入的权限。简写 *:insert

user:*:01 表示拥有对user资源实例01进行所有操作的权限

user:insert,user:update 简写 user:insert,update

相关方法

subject.hasRole(“”); 判断是否有角色

boolean hasRole = subject.hasRole("role1"); System.out.println(hasRole);

subject.hashRoles(List);分别判断用户是否具有List中每个内容

boolean[] hasRoles = subject.hasRoles(Arrays.asList("role1", "role2")); 
System.out.println(Arrays.toString(hasRoles));

subject.hasAllRoles(Collection);返回boolean,要求参数中所有角色用户都需要具有.

boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1", "role2")); 
System.out.println(hasAllRoles);

subject.isPermitted(“”);判断是否具有权限.

boolean permitted = subject.isPermitted("role1:update"); System.out.println(permitted);

subject.isPermitted(List);分别判断用户是否具有List中每个权限

boolean[] permitted1 = subject.isPermitted("role1:view", "role2:view"); 
System.out.println(Arrays.toString(permitted1));

subject.isPermittedAll(Collection);返回boolean,要求参数中所有权限都需要具有.

boolean permittedAll = subject.isPermittedAll("role1:view", "role2:view"); 
 System.out.println(permittedAll);

从以上的代码中可以看出我们的用户,密码,角色,权限都是在shrio.ini里面配置的,但是实际开发中肯定不是这样的,实际开发中我们的所有数据都是从数据库里面来的,如何实现呢,那就要使用数据和+自定义realm

自定义Realm实现授权

/**
 * 自定义Realm实现
 */

public class UserRealm extends AuthorizingRealm {

	 @Override
	 public String getName() {
		  return "UserRealm";
	 }

	 //用于认证
	 @Override
	 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		  //从token中获取身份信息
		  String username = (String)token.getPrincipal();
		  //根据用户名到数据库中取出用户信息 如果查询不到 返回null
		  String password = "1111";//假如从数据库中获取密码为1111
		  //返回认证信息 
		  SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, this.getName());
		  
		  return simpleAuthenticationInfo;
	 }
	
	
	 //用于授权
	 @Override
	 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		  //获取身份信息
		  String username = (String)principals.getPrimaryPrincipal();
		  //模拟根据身份信息获取权限数据
		  List<String> permissions = new ArrayList<String>();
		  permissions.add("user:save");
		  permissions.add("user:delete");
		  //将权限信息保存到AuthorizationInfo中
		  SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		  for(String permission:permissions){
		   simpleAuthorizationInfo.addStringPermission(permission);
		  }
		  return simpleAuthorizationInfo;
	}
	 
}

shiro.ini

# 自定义realm
userRealm = com.tuojun.realm.UserRealm
# 将realm设置到securityManager
securityManager.realms = $userRealm

发布了37 篇原创文章 · 获赞 16 · 访问量 6038

猜你喜欢

转载自blog.csdn.net/qq_44039966/article/details/104215781