Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权

Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权

一、Shiro授权:

1、授权与权限:

(1)授权:访问控制,必须具有该资源的访问权限才可以访问该资源。

(2)权限模型:标准权限数据模型包括 :用户、角色、权限(包括资源和权限)、用户角色关系、角色权限关系。

(3)权限分配:通过UI界面方便给用户分配权限,对上边权限模型进行增、删、改、查操作。

(4)权限控制:

第一种:基于角色的权限控制:根据角色判断是否有操作权限,因为角色的变化性较高,如果角色修改需要修改控制代码,系统可扩展性不强。

第二种:基于资源的权限控制:根据资源权限判断是否有操作权限,因为资源较为固定,如果角色修改或角色中权限修改不需要修改控制代码,使用此方法系统可维护性很强。建议使用。

(5)权限管理的解决方案:

①对于粗颗粒权限管理,建议在系统架构层面去解决,写系统架构级别统一代码(基础代码)。

粗颗粒权限:比如对系统的url、菜单、jsp页面、页面上按钮、类方法进行权限管理,即对资源类型进行权限管理。

②对于细颗粒权限管理:细颗粒权限管理是系统的业务逻辑,业务逻辑代码不方便抽取统一代码,建议在系统业务层进行处理。

粗颗粒权限:比如用户id为001的用户信息(资源实例)、类型为t01的商品信息(资源实例),对资源实例进行权限管理,可以理解为对数据级别的权限管理。

 

2、授权流程:

(1)对subject进行授权,调用方法isPermitted(”permission串”);

(2)SecurityManager执行授权,通过ModularRealmAuthorizer执行授权;

(3)ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据,调用realm的授权方法:doGetAuthorizationInfo;

(4)realm从数据库查询权限数据,返回ModularRealmAuthorizer;

(5)ModularRealmAuthorizer调用PermissionResolver进行权限串比对;

(6)如果比对后,isPermitted中”permission串”在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。

Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权

 

3、Shiro 支持三种方式的授权:

(1)编程式:通过写if/else 授权代码块完成:

Subject subject = SecurityUtils.getSubject();

if(subject.hasRole(“admin”)) {

//有权限

} else {

//无权限

}

(2)注解式:通过在执行的Java方法上放置相应的注解完成:

@RequiresRoles(“admin”)

public void hello() {

//有权限

}

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

<shiro:hasRole name=”admin”>

<!— 有权限—>

</shiro:hasRole>

 

 

二、Shiro授权示例程序:

1、入门的Shiro授权程序:

(1)编写shiro-permission.ini文件:

shiro-permission.ini文件里边的内容相当于在数据库查询出来的;

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

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

权限标识符号规则:资源:操作:实例(中间使用半角:分隔)

user:create:01  表示对用户资源的01实例进行create操作。

user:create    表示对用户资源进行create操作,相当于user:create:*,对所有用户资源实例进行create操作。

user:*:01  表示对用户资源实例01进行所有操作。

(2)程序编写:

//shiro的授权测试:
public class AuthorizationTest {

	//角色授权、资源授权测试:
	@Test
	public void testAuthorization(){
		Factory<SecurityManager> factory = new IniSecurityManagerFactory(
				"classpath:shiro-permission.ini");
		SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);
		SecurityUtils.setSecurityManager(securityManager);
		Subject subject = SecurityUtils.getSubject();
	
		UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
				"123456");
		try {
			subject.login(token);
		} catch (AuthenticationException e) {
			e.printStackTrace();
		}
		System.out.println("认证状态:" + subject.isAuthenticated());
		
		//认证通过之后执行授权:
		
		//基于角色的授权
		//hasRole传入角色标识:
		boolean ishasRole = subject.hasRole("role1");
		System.out.println("单个角色判断" + ishasRole);
		//hasAllRoles是否拥有多个角色:
		boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1","role2","role3"));
		System.out.println("多个角色判断" + hasAllRoles);
		// 使用check方法进行授权,如果授权不通过会抛出异常
		subject.checkRole("role2");
		
		//基于资源的授权:
		//isPermitted传入权限标识符
		boolean isPermitted = subject.isPermitted("user:create:1");
		System.out.println("单个权限判断" + isPermitted);

		boolean isPermittedAll = subject.isPermittedAll("user:create:1",
				"user:delete");
		System.out.println("多个权限判断" + isPermittedAll);
		
		// 使用check方法进行授权,如果授权不通过会抛出异常
		subject.checkPermission("items:delete:1");
	}
}

(3)执行结果:

Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权

至此,Shiro授权入门程序就完成了。在这个程序中,我们读取的是在shiro.ini配置文件中静态配置好的权限内容,但是在实际开发,我们通常是从数据库中查询用户所拥有的权限信息,因此,我们需要使用自定义的Realm进行从数据库中查询用户的权限信息。

 

2、自定义realm进行授权:

上面的程序是通过shiro-permission.ini对权限文件进行静态配置,在实际开发中,都是从数据库中获取权限数据。就需要自定义realm,由realm从数据库查询权限数据。

realm根据用户身份查询权限数据,将权限数据返回给authorizer(授权器)。

(1)自定义realm:

//自定义的Realm,需要继承AuthorizingRealm,并且重写这个类的两个方法
public class CustomRealm extends AuthorizingRealm{
	// 设置realm的名称
	@Override
	public void setName(String name) {
		super.setName("customRealm");
	}

	// 用于授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		
		//从principals获取身份信息
		//将getPrimaryPrincipal方法返回值转为真实身份(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中的身份类型)
		String userCode = (String) principals.getPrimaryPrincipal();
		
		//根据身份信息获取权限信息
		//连接数据库
		//模拟从数据库获取到数据
		List<String> permissions = new ArrayList<String>();
		permissions.add("user:create");//用户的创建
		permissions.add("items:add");//商品添加权限
		
		//查到权限数据,返回授权信息(要包括上边的permissions)
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		//将上边查询到授权信息填充到simpleAuthorizationInfo对象中
		simpleAuthorizationInfo.addStringPermissions(permissions);
		return simpleAuthorizationInfo;
	}
}

(2)编写shiro-realm.ini文件:

在shiro-realm.ini文件中配置自定义的realm,将realm设置到securityManager中。

[main]
#自定义的realm
customRealm=com.zwp.shiro.realm.CustomRealm
#将realm设置到securityManager,相当于spring中的注入
securityManager.realms=$customRealm

(3)测试:

	// 自定义realm进行资源授权测试
	@Test
	public void testAuthorizationCustomRealm() {

		Factory<SecurityManager> factory = new IniSecurityManagerFactory(
				"classpath:shiro-realm.ini");
		SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);
		Subject subject = SecurityUtils.getSubject();

		// 创建token令牌
		UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
				"123456");
		// 执行认证
		try {
			subject.login(token);
		} catch (AuthenticationException e) {
			e.printStackTrace();
		}
		System.out.println("认证状态:" + subject.isAuthenticated());
		
		// 认证通过后执行授权
		// 基于资源的授权,调用isPermitted方法会调用CustomRealm从数据库查询正确权限数据
		// isPermitted传入权限标识符,判断user:create:1是否在CustomRealm查询到权限数据之内
		boolean isPermitted = subject.isPermitted("user:create:1");
		System.out.println("单个权限判断" + isPermitted);
		boolean isPermittedAll = subject.isPermittedAll("user:create:1",
				"user:create");
		System.out.println("多个权限判断" + isPermittedAll);

		// 使用check方法进行授权,如果授权不通过会抛出异常
		subject.checkPermission("items:add:1");
	}

(4)测试结果:

Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权

至此,Shiro使用自定义Realm进行授权的程序就完成了。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/114710.html原文链接:https://javaforall.net

(0)
上一篇 2021年9月26日 下午8:00
下一篇 2021年9月26日 下午9:00


相关推荐

  • js中substr与substring的差别

    js中substr与substring的差别

    2021年11月16日
    36
  • CentOs安装Python3.9

    CentOs安装Python3.9下载python3源码包wgethttps://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz或者python官网下载https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz然后放过去解压缩源码包tar-zxvfPython-3.9.0.tgz进入源码包文件夹cdPython-3.9.0编译且安装进入源码包目录ls查看源码包内容释放编译文件Makefile.

    2022年6月16日
    101
  • 您的xshell评估期已过_xshell6编程语言

    您的xshell评估期已过_xshell6编程语言xshell6评估期已过,因为我下载的版本是evaluation版本,是有期限的。大家可以修改为Homeandschooluse的版本,这样就不会出现这个提示了。具体的操作步骤如下:1、前往下载地址,填写必填信息,邮箱一定要填写https://www.netsarang.com/download/down_form.html?code=6222、有限会收到一封邮件…

    2025年10月14日
    4
  • O泡果奶-APK反编译-Lua脚本

    O泡果奶-APK反编译-Lua脚本O泡果奶-APK反编译-Lua脚本反编译出的代码(有注释)–main.lua–require(“import”)import(“android.app.*”)import(“android.os.*”)import(“android.widget.*”)import(“android.view.*”)import(“android.view.View”)import(“android.content.Context”)import(“android.media.MediaPlay

    2026年1月17日
    2
  • FLP不可能原理(转)

    FLP不可能原理(转)1 FLPimpossibi 背景 FLPImpossibi FLP 不可能性 是分布式领域中一个非常著名的结果 该结果在专业领域被称为 定理 其地位之高可见一斑 该定理的论文是由 Fischer LynchandPatt 三位作者于 1985 年发表 之后该论文毫无疑问得获得了 Dijkstra 奖 顺便要提一句的是 Lynch 是一位非常著名的分布式领域的女性科学家

    2026年3月18日
    2
  • 【APICloud系列|29】dialogBox模块(对话框)的实现

    【APICloud系列|29】dialogBox模块(对话框)的实现导读 dialogBox 封装了十一种款式的对话框 每一种款式都提供一个接口来调用 开发者可按照各个接口的样式来自定义对话框上的文字 图片 图文等把 dialogBox 模块的 11 个样式分别实现个简单的效果 其中将 alert 方法做了两个样式 如果你觉得我写的样式够丑 请不要喷我 因为我是程序猿 呵呵了 如果你接受了就直接用到你的项目 否则自己再根据官方的文档和结合自己的产品需求 来定义更多高大上的样式 接下来我拿几个我常用的方法给大家简单介绍下 其它的大家可以看看模块的视频效果以后 自

    2026年3月20日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号