用户授权也成为用户访问权限控制,指应用中用户可以访问的资源路径或页面或功能,在用户授权功能中,需要知道以下几个对象:
主体:Subject
指请求应用的用户,在Shiro中使用Subject代表该用户,该用户只有通过授权后才允许访问对应的资源。
角色:Role
角色代表了操作的集合或权限的集合,一般情况下我们会赋予用户的是角色而不是权限,即用户直接和角色进行关联,角色再和权限进行关联。
权限:Permission
权限在百度百科中是指为了保证职责的有效履行,任职者必须具备的,对某事项进行决策的范围和程度,在安全策略中为原子授权单位,通过权限我们可以设置用户访问应用中某个功能的权力,比如我们常用的CURD等。
资源:Resource
资源再应用程序中,指某个页面或功能对应的有效路径,如登录/login,退出/logout,404错误页面/404.html等即为资源。
主要使用方法:
subject.hasRole("role");判断用户是否有某个角色
subject.hasRole(list);分别判断用户时候具有List集合中的每个角色
subject.hasAllRoles(collection);返回一个boolean值,要求参数中所有角色用户都要有
subject.isPermitted("permission");判断是否有权限
本文在前文Shiro框架(三)-Shiro实现身份认证功能的功能上继续进行开发,小伙伴们可以点击链接前去参考。
1、修改shiro.ini文件,添加roles配置增加角色,修改users增加用户的角色,内容如下:
#配置用户
[users]
user1=123,role1
user2=1234,role2,role3
user3=12345,role3
#配置角色和权限
[roles]
role1=menu:save,menu:delete,menu:update,menu:query
role2=menu:save,menu:query,menu:export
role3=menu:query
2、src/main/java目录下新建类ShiroAuthorization,代码如下:
package com.hongke.shiro;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
/**
* @description 用户权限认证
* @title ShiroAuthorization.java
* @package com.hongke.shiro
* @author chengjunyu
* @date 2020-03-28 15:41:46
*/
public class ShiroAuthorization {
public static void main(String[] args) {
String username = "user1";
String password = "123";
/*
* 创建安全管理器工厂,选择org.apache.shiro.util包下的Factory,从ini文件下读取信息
*/
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
/*
* 从工厂中获取SecurityManager对象
*/
SecurityManager securityManager = factory.getInstance();
/*
* 绑定SecurityManager到当前线程
*/
SecurityUtils.setSecurityManager(securityManager);
/*
* 取出当前Subject主体,来自于SecurityManager
*/
Subject subject = SecurityUtils.getSubject();
/*
* 将用户名和密码存入token中
*/
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
/*
* 登录认证
*/
System.out.println("用户"+username+"将要登录,登录密码为"+password);
try {
subject.login(usernamePasswordToken);
System.out.println("用户"+username+"登录成功");
}catch (AuthenticationException e) {
System.out.println("用户"+username+"账号不存在或密码错误");
}
/*
* 判断用户是否有某个角色
*/
String roleFirst = "role1";
String roleSecond = "role2";
String roleThird = "role3";
String hasRole1 = subject.hasRole(roleFirst)?"用户有角色"+roleFirst:"用户无角色"+roleFirst;
System.out.println("用户"+username+"是否有角色"+roleFirst+":"+hasRole1);
String hasRole2 = subject.hasRole(roleSecond)?"用户有角色"+roleSecond:"用户无角色"+roleSecond;
System.out.println("用户"+username+"是否有角色"+roleSecond+":"+hasRole2);
/**
* 在JDK1.8版本中,new ArrayList后不需要再指定类型,此处我使用的是JDK1.5,不做修改了
*/
/*
* 判断用户是否同时拥有集合中的所有角色
*/
Collection<String> rolesCollection = new ArrayList<String>();
rolesCollection.add(roleFirst);
rolesCollection.add(roleSecond);
rolesCollection.add(roleThird);
String hasAllRoles = subject.hasAllRoles(rolesCollection)?"同时拥有":"未同时拥有";
System.out.println("用户"+username+"是否同时拥有角色"+rolesCollection+":"+hasAllRoles);
/*
* 分别判断用户是否有集合中的某个角色
*/
boolean[] hasRoles = subject.hasRoles((List<String>)rolesCollection);
System.out.println("用户"+username+"是否有角色"+rolesCollection+":"+Arrays.toString(hasRoles));
/*
* 判断用户是否有某个权限
*/
String permittedFirst = "menu:save";
String permittedSecond = "menu:delete";
String permittedThird = "menu:update";
String permittedFourth = "menu:query";
String permittedFifth = "menu:export";
String hasPermission1 = subject.isPermitted(permittedFirst)?"用户有权限"+permittedFirst:"用户无权限"+permittedFirst;
System.out.println("用户"+username+"是否有权限"+permittedFirst+":"+hasPermission1);
String hasPermission2 = subject.isPermitted(permittedFifth)?"用户有权限"+permittedFifth:"用户无权限"+permittedFifth;
System.out.println("用户"+username+"是否有权限"+permittedFifth+":"+hasPermission2);
String[] permissionsArr = {permittedFirst, permittedSecond, permittedThird, permittedFourth, permittedFifth};
/*
* 判断用户是否同时拥有数组中的所有权限
*/
String hasAllPermissions= subject.isPermittedAll(permissionsArr)?"同时拥有":"未同时拥有";
System.out.println("用户"+username+"是否同时拥有权限"+Arrays.toString(permissionsArr)+":"+hasAllPermissions);
/*
* 分别判断用户是否拥有数组中的某个权限
*/
boolean[] hasPermissions = subject.isPermitted(permissionsArr);
System.out.println("用户"+username+"是否有权限"+Arrays.toString(permissionsArr)+":"+Arrays.toString(hasPermissions));
}
}
运行结果如下: