ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

shiro入门demo(二)授权

2026/8/11 18:29:36 拓冰建站 浏览量
shiro入门demo(二)授权

在前面认证的基础上,认证通过后进行授权操作。授权根据业务需求有两种维度,基于角色的授权和基于资源的授权。

一、授权-基于角色授权:

  shiro中授权实现方式:有三种

1、编程式
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {//有权限
} else {//无权限
}编程式又有两种方式:(1)hasRole、hasAllRoles 返回值true/false(2)checkRole、checkRoles 只要验证失败就报异常2、注解式
@RequiresRoles("admin")
public void hello() {//有权限
}3、标签式
JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:
<shiro:hasRole name="admin"><!— 有权限—>
</shiro:hasRole>
注意: Thymeleaf 中使用shiro需要额外集成!

 这里以第一种编程式为例

1、配置文件mock数据实现:

  新建shiro-user-role.ini配置文件

[users]
zs=123,role1
ls=123,role2
admin=123,role1,role2

 单元测试

  /*** 以admin/123用户为例*/@Testpublic void testRole(){//1、创建SecurityManagerFactory 读取ini数据源文件IniSecurityManagerFactory factory=new IniSecurityManagerFactory("classpath:shiro-user-role.ini");//2、创建安全管理器SecurityManagerSecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);//3、通过SecurityUtil获取登入用户主体subjectSubject subject = SecurityUtils.getSubject();//4、创建登入令牌tokenUsernamePasswordToken token=new UsernamePasswordToken("admin", "123");//用户认证(shiro的核心功能之一)try {//异常//1.org.apache.shiro.authc.UnknownAccountException:账号错误异常//2.org.apache.shiro.authc.IncorrectCredentialsException:密码错误异常//3.org.apache.shiro.authz.UnauthorizedException: 授权错误异常subject.login(token);System.out.println("认证成功");} catch (AuthenticationException e) {System.out.println("认证失败");e.printStackTrace();}//角色验证try {//方式一:hasRole 返回值true/falseif (subject.hasRole("role1")) {System.out.println("角色验证成功");} else {System.out.println("角色验证失败");}//方式二:checkRole 只要验证失败就报异常//subject.checkRole("role1");//System.out.println("角色验证成功");//hasRoles: 参数List集合 返回boolean数组 返回顺序与传递顺序一一对应 传普通用户,高级用户,管理员 返回false,false,true//hasAllRoles: 参数Collection集合 返回true/false 如果有一个角色验证失败就返回false} catch (Exception e) {System.out.println("角色验证失败");e.printStackTrace();}//7、安全退出subject.logout();}

输出:认证成功 角色验证成功;

密码错误,角色正确,输出:

密码正确,改成错误的角色,输出:

2、Realm域实现:和下面资源授权合并,见下文。 

二、授权-基于资源授权 :

  资源权限编程式验证有两种方式:

(1)isPermitted、isPermittedAll方式,返回值true/false
(2)checkPermission、checkPermissions方式,只要验证失败就报异常

1、配置文件实现:

  新建shiro-user-role-permisson.ini配置文件:

[users]
zs=123,role1
ls=123,role2
admin=123,role1,role2,role4[roles]
role1=system:user:add
role2=system:user:add,system:user:select
role3=system:user:add,system:user:select,system:user:update,system:user:delete
role4=system:*:*

  单元测试:在前面的基础上加上资源权限验证即可

 /*** 以admin/123用户为例*/@Testpublic void testRole(){//1、创建SecurityManagerFactory 读取ini数据源文件IniSecurityManagerFactory factory=new IniSecurityManagerFactory("classpath:shiro-user-role-permisson.ini");//2、创建安全管理器SecurityManagerSecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);//3、通过SecurityUtil获取登入用户主体subjectSubject subject = SecurityUtils.getSubject();//4、创建登入令牌tokenUsernamePasswordToken token=new UsernamePasswordToken("admin", "123");//用户认证(shiro的核心功能之一)try {//异常//1.org.apache.shiro.authc.UnknownAccountException:账号错误异常//2.org.apache.shiro.authc.IncorrectCredentialsException:密码错误异常//3.org.apache.shiro.authz.UnauthorizedException: 授权错误异常subject.login(token);System.out.println("认证成功");} catch (AuthenticationException e) {System.out.println("认证失败");e.printStackTrace();}//角色验证try {//方式一:hasRole 返回值true/falseif (subject.hasRole("role3")) {System.out.println("角色验证成功");} else {System.out.println("角色验证失败");}//方式二:checkRole 只要验证失败就报异常//subject.checkRole("role1");//System.out.println("角色验证成功");//hasRoles: 参数List集合 返回boolean数组 返回顺序与传递顺序一一对应 传普通用户,高级用户,管理员 返回false,false,true//hasAllRoles: 参数Collection集合 返回true/false 如果有一个角色验证失败就返回false} catch (Exception e) {System.out.println("角色验证失败");e.printStackTrace();}try {//isPermitted方式if (subject.isPermitted("system:user:update")) {System.out.println("权限验证成功");} else {System.out.println("权限验证失败");}//checkPermission方式//subject.checkPermission("system:user:update");//System.out.println("权限验证成功");} catch (Exception e) {System.out.println("权限验证失败");e.printStackTrace();}//7、安全退出subject.logout();}

输出

输入错误的权限如system1:user:update,报错:

Permission字符串通配符权限:

(1)规则:资源标志符:操作:对象实例id;

(2)*表示任意资源/操作/实例。

2、 Realm域实现:

(1)自定义域:

package com.demo.shiro.realm;import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;public class MyRolePermissionRealm1 extends AuthorizingRealm {//授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {String primaryPrincipal = (String) principal.getPrimaryPrincipal();//用户名System.out.println("身份信息:"+primaryPrincipal);if(!"admin".equals(primaryPrincipal)){return null;}//根据用户查询角色、资源权限SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();//1、角色simpleAuthorizationInfo.addRole("role1");simpleAuthorizationInfo.addRole("role2");//2、资源simpleAuthorizationInfo.addStringPermission("system:*:*");return simpleAuthorizationInfo;}//认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String) token.getPrincipal();String password = new String((char[]) token.getCredentials());if(!"admin".equals(username)){throw new UnknownAccountException();}if(!"123".equals(password)){throw new IncorrectCredentialsException();}SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,password,this.getName());return simpleAuthenticationInfo;}
}

以同样的方式实现zs、ls的授权Realm:

public class MyRolePermissionRealm2 extends AuthorizingRealm {//授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {String primaryPrincipal = (String) principal.getPrimaryPrincipal();//用户名System.out.println("身份信息:"+primaryPrincipal);if(!"zs".equals(primaryPrincipal)){return null;}//根据用户查询角色、资源权限SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();//1、角色simpleAuthorizationInfo.addRole("role1");//2、资源simpleAuthorizationInfo.addStringPermission("system:user:add");return simpleAuthorizationInfo;}//认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String) token.getPrincipal();String password = new String((char[]) token.getCredentials());if(!"zs".equals(username)){throw new UnknownAccountException();}if(!"123".equals(password)){throw new IncorrectCredentialsException();}SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,password,this.getName());return simpleAuthenticationInfo;}
}
public class MyRolePermissionRealm3 extends AuthorizingRealm {//授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {String primaryPrincipal = (String) principal.getPrimaryPrincipal();//用户名System.out.println("身份信息:"+primaryPrincipal);if(!"ls".equals(primaryPrincipal)){return null;}//根据用户查询角色、资源权限SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();//1、角色simpleAuthorizationInfo.addRole("role2");//2、资源simpleAuthorizationInfo.addStringPermission("system:user:add");simpleAuthorizationInfo.addStringPermission("system:user:select");return simpleAuthorizationInfo;}//认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String) token.getPrincipal();String password = new String((char[]) token.getCredentials());if(!"ls".equals(username)){throw new UnknownAccountException();}if(!"123".equals(password)){throw new IncorrectCredentialsException();}SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,password,this.getName());return simpleAuthenticationInfo;}
}

(2)单元测试:

 /*** 以admin/123用户为例*/@Testpublic void testRole(){/* //1、创建SecurityManagerFactory 读取ini数据源文件IniSecurityManagerFactory factory=new IniSecurityManagerFactory("classpath:shiro-user-role-permisson.ini");//2、创建安全管理器SecurityManagerSecurityManager securityManager = factory.getInstance();*///编程设置realmDefaultSecurityManager securityManager = new DefaultSecurityManager();List<Realm> realms = new ArrayList<>();realms.add(new MyRolePermissionRealm1());realms.add(new MyRolePermissionRealm2());realms.add(new MyRolePermissionRealm3());securityManager.setRealms(realms);SecurityUtils.setSecurityManager(securityManager);//3、通过SecurityUtil获取登入用户主体subjectSubject subject = SecurityUtils.getSubject();//4、创建登入令牌tokenUsernamePasswordToken token=new UsernamePasswordToken("admin", "123");//用户认证(shiro的核心功能之一)try {//异常//1.org.apache.shiro.authc.UnknownAccountException:账号错误异常//2.org.apache.shiro.authc.IncorrectCredentialsException:密码错误异常//3.org.apache.shiro.authz.UnauthorizedException: 授权错误异常subject.login(token);System.out.println("认证成功");} catch (AuthenticationException e) {System.out.println("认证失败");e.printStackTrace();}//角色验证try {//方式一:hasRole 返回值true/falseif (subject.hasRole("role1")) {System.out.println("角色验证成功");} else {System.out.println("角色验证失败");}//方式二:checkRole 只要验证失败就报异常//subject.checkRole("role1");//System.out.println("角色验证成功");//hasRoles: 参数List集合 返回boolean数组 返回顺序与传递顺序一一对应 传普通用户,高级用户,管理员 返回false,false,true//hasAllRoles: 参数Collection集合 返回true/false 如果有一个角色验证失败就返回false} catch (Exception e) {System.out.println("角色验证失败");e.printStackTrace();}try {//isPermitted方式if (subject.isPermitted("system:user:update")) {System.out.println("权限验证成功");} else {System.out.println("权限验证失败");}//checkPermission方式//subject.checkPermission("system:user:update");//System.out.println("权限验证成功");} catch (Exception e) {System.out.println("权限验证失败");e.printStackTrace();}//7、安全退出subject.logout();}