3 Apache Shiro 授权
来源:互联网 发布:c 面向对象编程流程 编辑:程序博客网 时间:2024/06/05 07:52
3.1 概述
授权,又称访问控制,即在应用中控制用户可以使用哪些资源(如访问页面、页面操作、数据操作等),覆盖以下几个概念:
(1) 主体(Subject)
即用户,Shiro 中使用 Subject 代表用户。
(2) 角色(Role)
代表权限的集合,可以将权限集合起来一次性赋予用户。
(3) 权限(Permission)
安全策略中的原子授权单位,权限表示操作某个资源的能力。
(4) 资源(Resource)
应用中可以访问或操作的资源、如页面、数据、业务方法等。
角色又分为:
隐式角色
直接通过角色验证用户是否有某资源的操作权限。如果需要取消该权限,需要将用户对应的角色去除,属于粗粒度的权限控制。
显式角色
通过角色绑定的权限集合验证用户是否有某资源的操作权限。如果需要取消该权限,只需要将该权限从角色绑定的权限集合中去除,不需要去除用户的角色,属于细粒度的权限控制。
3.2 授权方式
Shiro 支持三种授权方式:
(1) 编程式
通过写 if/else
授权代码块实现
(2) 注解式
通过在执行的 Java 方法上放置注解 @RequiresRoles("admin")
实现
(3) JSP/GSP 标签
通过在 JSP/GSP 页面添加标签 <shiro:hasRole>
实现
3.3 授权实现
(1) 基于角色的访问控制(隐式角色)
首先,在 ini 配置文件(shiro-role.ini)中配置用户拥有的角色。
[users]Steve=001,role1,role2Tony=002,role1
在 ini 配置文件中配置用户角色规则:
用户名=密码,角色1,角色2,…
如果需要在应用中判断用户是否具有相应角色,需要在相应的 Realm
中返回角色信息,Shiro 不负责维护用户和角色的信息,需要应用自己提供,Shiro 只提供相应接口实现验证。
其次,编写测试用例。
import static org.junit.Assert.assertFalse;import static org.junit.Assert.assertTrue;import java.util.Arrays;import org.apache.shiro.SecurityUtils;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;import org.apache.shiro.util.ThreadContext;import org.junit.After;import org.junit.Test;public class ShiroTest { @Test public void testHasRole() { login("classpath:shiro-role.ini", "Steve", "001"); assertTrue(subject().hasRole("role1")); assertTrue(subject().hasRole("role2")); boolean[] result = subject().hasRoles(Arrays.asList("role1", "role2", "role3")); assertTrue(result[0]); assertTrue(result[1]); assertFalse(result[2]); } private void login(String configFile, String username, String password) { // 1.获取SecurityManager工厂,使用ini配置文件初始化SecurityManager Factory<SecurityManager> factory = new IniSecurityManagerFactory(configFile); // 2.获取SecurityManager实例 SecurityManager securityManager = factory.getInstance(); // 3.将SecurityManager实例绑定给SecurityUtils SecurityUtils.setSecurityManager(securityManager); // 4.通过SecurityUtils获取Subject Subject subject = SecurityUtils.getSubject(); // 5.创建用户名、密码身份验证token UsernamePasswordToken token = new UsernamePasswordToken(username, password); // 6.使用用户名、密码身份验证token进行身份认证,即登录 subject.login(token); } private Subject subject() { return SecurityUtils.getSubject(); } @After public void tearDown() { // 如果需要同时运行多个test方法,在每个方法退出时需要解除绑定到当前线程的Subject实例,否则会影响接下来的test方法的执行。 ThreadContext.unbindSubject(); }}
Shiro 提供 boolean hasRole(String roleIdentifier)
和 boolean[] hasRoles(List<String> roleIdentifiers)
方法用于判断用户是否拥有某个角色。
Shiro 还提供了 void checkRole(String roleIdentifier) throws AuthorizationException
和 void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException
方法检查用户是否拥有某个角色,与 hasRole
和 hasRoles
方法的不同之处在于:如果检查出用户不具有某种角色,hasRole
和 hasRoles
方法会返回 false
,而 checkRole
和 checkRoles
方法会抛出 UnauthorizedException
异常。
测试用例(上个测试用例中其它方法不变,只需要将 testHasRole
方法替换为 testCheckRole
方法):
@Test(expected = UnauthorizedException.class)public void testCheckRole() { login("classpath:shiro-role.ini", "Steve", "001"); subject().checkRole("role1"); subject().checkRoles(Arrays.asList("role1", "role3"));}
(2) 基于资源的访问控制(显式角色)
首先,在 ini 配置文件(shiro-permission.ini)中配置用户拥有的角色及角色、权限关系。
[users]Steve=001,role1,role2Tony=002,role1[roles]#对资源user拥有create和update权限role1=user:create,user:update#对资源user拥有create和delete权限role2=user:create,user:delete
在 ini 配置文件中配置角色、权限关系的规则:
角色=权限1,权限2,…
配合之前介绍的配置用户角色规则:
用户名=密码,角色1,角色2,…
可知,先根据用户名和密码进行身份认证,通过后根据用户名找到角色,再根据角色找到对应的权限集合。
其次,编写测试用例。
@Testpublic void testIsPermitted() { login("classpath:shiro-permission.ini", "Steve", "001"); assertTrue(subject().isPermitted("user:create")); assertTrue(subject().isPermittedAll("user:update", "user:delete")); assertFalse(subject().isPermitted("user:view"));}
Shiro 提供了 boolean isPermitted(String permission)
和 boolean isPermittedAll(String... permissions)
方法用于判断用户是否拥有某权限。
Shiro 还提供了 void checkPermission(String permission) throws AuthorizationException
和 void checkPermissions(String... permissions) throws AuthorizationException
方法检查用户是否拥有某权限,如果检查出用户不拥有目标权限,会抛出 UnauthorizedException
异常。
测试用例:
@Test(expected = UnauthorizedException.class)public void testCheckPermission() { login("classpath:shiro-permission.ini", "Steve", "001"); subject().checkPermission("user:create"); subject().checkPermissions("user:update", "user:delete"); subject().checkPermission("user:view");}
3.4 字符串通配符权限
规则:资源标识符:操作:对象实例ID,即对哪个资源的哪个实例执行何种操作。其中:
- “:”用于分隔资源/操作/实例
- “,”用于分隔多个操作
- “*”用于表示任意资源、操作或实例
(1) 单个资源的单个权限
java:subject().checkPermissions("system:user:create");
资源 system:user
的 create
权限。
(2) 单个资源的多个权限
ini:role41=system:user:update,system:user:delete
java:subject().checkPermissions("system:user:update", "system:user:delete");
资源 system:user
的 update
和 delete
权限。
可以简写为:
ini:role42="system:user:update,delete"
java:subject().checkPermissions("system:user:update,delete");
注意:通过 "system:user:update,delete"
验证 "system:user:update", "system:user:delete"
是没问题的,但是反过来规则不成立。
(3) 单个资源的全部权限
(4) 所有资源的全部权限
(5) 实例级别的权限
- 3 Apache Shiro 授权
- Apache Shiro 关于Shiro 授权
- Apache Shiro 授权
- Apache Shiro 授权概念
- Apache Shiro 授权过程
- Apache Shiro 授权例子
- Apache Shiro 授权
- Apache Shiro (三) ---- 授权
- Apache Shiro 授权例子
- Apache Shiro 编程方式授权
- Apache Shiro 注解方式授权
- Apache Shiro 标签方式授权
- Apache Shiro 基于权限授权
- Apache Shiro 标签方式授权
- Apache Shiro 标签模式授权
- Apache Shiro 标签方式授权
- Apache Shiro--身份验证与授权
- Apache Shiro 标签模式授权
- 24.Spring_与Web应用整合
- WebRTC Part1
- Android drawable微技巧,你所不知道的drawable的那些细节
- 1056. Mice and Rice (25)
- leetcode 563. Binary Tree Tilt
- 3 Apache Shiro 授权
- c++实现最大堆建立(链表结构)和堆排序
- 案例-----简易新闻客户端
- linux16.04+cuda8.0+opencv3.1
- VMware虚拟机三种网络模式详解 Bridged(桥接模式)
- winpython下载安装
- Unity2d Sqlite
- xss攻击
- 【OpenCV3图像处理】形态学 --- 膨胀、腐蚀、开运算 闭运算、形态学梯度、顶帽运算、黑帽运算