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进行授权的程序就完成了。

 

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 大数据分析应用的机遇与挑战「建议收藏」

    大数据分析应用的机遇与挑战「建议收藏」随着信息技能的发展,互联网家当的进步,计算机数据处理能力的快速增长,电子商务的日新月异及各种社交媒体的传播扩散,各种信息无时无刻不在影响着我们的生活。我们每时每刻都在自觉或者不自觉得与数据打交道,成为数据的记录者与传播者。海量数据的处理,以及如何利用大数据营销,给我们提出了更多的挑战。在这个人人都高喊“大数据时代”的今天,数据似乎被提到一个前所未有的高度。无论是个人还是企业,无论是网络营销还是线…

  • 宋宝华: 纪念金庸先生——程序员的武侠世界

    在漫天的星河中,有这样一颗星,他朴实无华,却又熠熠生辉,照亮了无数人的人生。他就是金庸先生。随着一代大侠的驾鹤西去,“飞雪连天射白鹿,笑书神侠倚碧鸳”,成为绝响。 每一个…

  • 基于51单片机的毕业设计作品_毕业设计能拿公司项目吗

    基于51单片机的毕业设计作品_毕业设计能拿公司项目吗以下是学长亲手整理的C51单片机相关的毕业设计选题,都是经过学长精心审核的题目,适合作为毕设,难度不高,工作量达标,对毕设有任何疑问都可以问学长哦!相对容易工作量达标题目新颖,含创新点httpshttpshttpshttpshttpshttps。……

  • 【知识普及】平板的屏幕分辨率和屏幕比例_和平精英平板分辨率

    【知识普及】平板的屏幕分辨率和屏幕比例_和平精英平板分辨率针对IOS,Android手机分辨率大小、屏幕尺寸、开发尺寸的参考。在实际页面的开发过程,往往显示屏幕的宽度换算为像素尺寸的1/2。IOS:6.5英寸——1242x2688px——XsMax6.1英寸——828x1792px——XR5.8英寸——1125x2436px——X/Xs5.5英寸——1242x2208px——6+…

  • 你的礼物

    你的礼物你的礼物

  • PXE+Kickstart 高效批量网络装机

    PXE+Kickstart 高效批量网络装机文章目录1.PXE概述1.1PXE定义1.2PXE批量部署的优点1.3PXE搭建的前提条件1.4PXE架构示意图2.搭建PXE远程安装服务器2.1安装并启用TFTP服务2.2安装并启用DHCP服务2.3准备Linux内核、初始化镜像文件2.4准备PXE引导程序1.PXE概述1.1PXE定义  PXE(预启动执行环境,在操作系统之前运行)是由Intel公司开发的网络引导技术,工作在Client/Server模式,允许客户机通过网络从远

发表回复

您的电子邮箱地址不会被公开。

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