概念

授权,又称作为访问控制,是对资源的访问管理的过程,即对于认证通过的用户,授予他可以访问某些资源的权限。

授权的方式

shiro支持三种方式的授权:

代码触发

通过写if/else 授权代码块完成

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}

注解触发

通过在执行的Java方法上放置相应的注解完成

@RequiresRoles("admin")
public void hello() {
//有权限
}

标签触发

在JSP/GSP页面通过相应的标签完成

<shiro:hasRole name="admin">
<!— 有权限—>
</shiro:hasRole>

注意本文先讲代码触发,后面两种情况再后面案例中使用讲解。

授权流程图

Shiro教程4(授权操作)_运行环境Shiro教程4(授权操作)_自定义_02

简单授权实现

在ini.xml文件中设置

[users]
#用户zhang的密码是123,此用户具有role1和role2两个角色
zhang=123,role1,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

验证角色和权限

@Test
public void test() {
// 1.获取SecurityManager工厂对象
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
// 2.通过Factory对象获取SecurityManager对象
SecurityManager securityManager = factory.getInstance();
// 3.将SecurityManager对象添加到当前运行环境中
SecurityUtils.setSecurityManager(securityManager);

// 4.获取Subject对象
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("zhang", "123");
// 登录操作
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("账号出错...");
} catch(IncorrectCredentialsException e){
System.out.println("密码出错...");
}
// 获取登录的状态
System.out.println(subject.isAuthenticated());
// 认证通过后进行权限验证 角色
System.out.println(subject.getPrincipal()+"是否具有role1角色:"+subject.hasRole("role1"));
System.out.println(subject.getPrincipal()+"是否具有role3角色:"+subject.hasRole("role3"));
boolean[] types = subject.hasRoles(Arrays.asList("role1","role2"));
System.out.println(subject.getPrincipal()+"是否具有role1和role2角色:"+types[0]+","+types[1]);
//subject.checkRole("role1");
//subject.checkRole("role3");
// 验证权限
System.out.println(subject.getPrincipal()+"是否具有user:create权限:"+subject.isPermitted("user:create"));
System.out.println(subject.getPrincipal()+"是否具有user:delete角色:"+subject.isPermitted("user:delete"));
boolean t = subject.isPermittedAll("user:create","user:delete");
System.out.println(subject.getPrincipal()+"是否具有user:create和user:delete的权限:"+t);
}

输出结果:

true
zhang是否具有role1角色:true
zhang是否具有role3角色:false
zhang是否具有role1和role2角色:true,true
zhang是否具有user:create权限:true
zhang是否具有user:delete角色:true
zhang是否具有user:create和user:delete的权限:true

注意

subject.checkRole("role3");
subject.checkPermission("aaa");

检查是否存在该角色和权限,如果不存在则会抛异常

Shiro教程4(授权操作)_运行环境_03Shiro教程4(授权操作)_自定义_04

自定义领域授权

重写授权的方法

/**
* 授权方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取当前登录的账号
String userName = (String) principals.getPrimaryPrincipal();
// 根据账号信息 可以去数据库中查询出该账号对应的 角色和权限信息

List<String> roles = new ArrayList<>();
roles.add("r1");
roles.add("r2");
roles.add("r3");

List<String> ps = new ArrayList<>();
ps.add("order:create");
ps.add("order:query");
ps.add("order:delete");

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 添加角色
info.addRole("role1");
info.addRoles(roles);
// 添加权限
info.addStringPermission("user:update");
info.addStringPermissions(ps);
return info;
}

ini.xml文件

[main]
#自定义 realm
customRealm=com.dpb.realm.MyRealm
#将realm设置到securityManager
securityManager.realms=$customRealm

测试方法和之前一样

@Test
public void test() {
// 1.获取SecurityManager工厂对象
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 2.通过Factory对象获取SecurityManager对象
SecurityManager securityManager = factory.getInstance();
// 3.将SecurityManager对象添加到当前运行环境中
SecurityUtils.setSecurityManager(securityManager);

// 4.获取Subject对象
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("root", "123456");
// 登录操作
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("账号出错...");
} catch (IncorrectCredentialsException e) {
System.out.println("密码出错...");
}
// 获取登录的状态
System.out.println(subject.isAuthenticated());

// 获取登录的状态
System.out.println(subject.isAuthenticated());
// 认证通过后进行权限验证 角色
System.out.println(subject.getPrincipal() + "是否具有role1角色:" + subject.hasRole("role1"));
System.out.println(subject.getPrincipal() + "是否具有role3角色:" + subject.hasRole("role3"));
boolean[] types = subject.hasRoles(Arrays.asList("role1", "role2"));
System.out.println(subject.getPrincipal() + "是否具有role1和role2角色:" + types[0] + "," + types[1]);
// subject.checkRole("role1");
//subject.checkRole("role3");
// 验证权限
System.out.println(subject.getPrincipal() + "是否具有user:create权限:" + subject.isPermitted("user:create"));
System.out.println(subject.getPrincipal() + "是否具有user:delete角色:" + subject.isPermitted("user:delete"));
boolean t = subject.isPermittedAll("user:create", "user:delete");
System.out.println(subject.getPrincipal() + "是否具有user:create和user:delete的权限:" + t);
//subject.checkPermission("aaa");
}


Java帮帮

非盈利学习社区

官网:www.javahelp.com.cn

Shiro教程4(授权操作)_运行环境_05


职涯宝

时间宝贵,阅读价值

官网:www.zhiya360.com

Shiro教程4(授权操作)_运行环境_06


九点编程

深夜学习,未来可期

Shiro教程4(授权操作)_官网_07


悟空教程

强大自己,立于不败

Shiro教程4(授权操作)_官网_08


Python帮帮

人工智能,不得不看

Shiro教程4(授权操作)_自定义_09