Shiro(2)---授权

xiaoxiao2021-02-27  196

Shiro授权

1.授权流程

2.授权方式

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>

3.入门测试程序

测试分为基于角色的权限控制和基于资源的权限控制(开发中建议使用)

1. 创建shiro-permission.ini文件模拟数据源

#用户 [users] #用户zhang的密码是123,此用户具有role1和role2两个角色 zhang=123,role1,role2 wang=123,role2 #权限 [roles] #角色role1对资源user拥有createupdate权限 role1=user:create,user:update #角色role2对资源user拥有createdelete权限 role2=user:create,user:delete #角色role3对资源user拥有create权限 role3=user:create

权限标识符号规则:资源:操作:实例(中间使用半角:分隔) user:create:01 表示对用户资源的01实例进行create操作。 user:create 表示对用户资源进行create操作,相当于user:create:*,对所有用户资源实例进行create操作。 user:*:01 表示对用户资源实例01进行所有操作。

2. 测试代码

public void testPermission(){ //根据ini文件创建SecurityManagerFactory Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini"); SecurityManager securityManager = factory.getInstance(); //将securityManager设置到运行环境中 SecurityUtils.setSecurityManager(securityManager); //创建主体对象 Subject subject = SecurityUtils.getSubject(); //有身份和凭证信息生成一个token UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); } boolean isAuthenticated = subject.isAuthenticated(); System.out.println("用户认证状态: "+isAuthenticated); //基于角色的权限控制 boolean isHasRole1 = subject.hasRole("role1"); System.out.println("是否有role1角色: "+isHasRole1); boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1","role2","role3")); System.out.println("是否有所有角色: "+hasAllRoles); //使用check进行授权,如果授权失败则拋异常 subject.checkRole("role1"); subject.checkRoles("role1","role2"); //基于资源的权限控制 boolean isPermitted = subject.isPermitted("user:create"); System.out.println("是否拥有该权限: "+isPermitted); boolean isPermittedAll = subject.isPermittedAll("user:create:1","user:delete"); System.out.println("是否拥有所有的权限: "+isPermittedAll); //使用check进行授权,如果授权失败则拋异常 subject.checkPermission("user:create"); subject.checkPermissions("user:create","user:delete"); }

4.自定义realm

这里用到的是基于资源的权限控制 1.在自定义realm完善doGetAuthorizationInfo()方法

// 授权 protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { //获取身份信息 String principal = (String)principals.getPrimaryPrincipal(); //根据身份信息从数据库中获取权限数据 //使用静态数据进行模拟... List<String> permissions = new ArrayList<String>(); permissions.add("user:create"); permissions.add("user:delete"); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); //将权限数据封装到SimpleAuthorizationInfo对象中 simpleAuthorizationInfo.addStringPermissions(permissions); return simpleAuthorizationInfo; }

2.ini配置文件还使用认证阶段使用的,不用改变。

[main] #自定义realm customRealm=com.ak.shiro.CustomRealm #将realm设置到securityManager securityManager.realms=$customRealm

5.授权流程

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

2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权

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

4、realm从数据库查询权限数据,并返回给ModularRealmAuthorizer

5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对

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

转载请注明原文地址: https://www.6miu.com/read-16724.html

最新回复(0)