第四章:基于角色和权限的权限认证

最后的工程结构:

   

 

-------------------------------------------------------

复制第三章的工程Shiro02, 改名Shiro03

-------------------------------------------------------

(1)基于角色的权限认证

一、加入Junit测试类, 修改pom.xml

<!-- 引入测试类Junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>

二、封装第三章的测试代码,封装成一个工具类,方便日后使用

ShiroUtil.java

package com.java1234.common;

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;

/**
 * 工具类
 */
public class ShiroUtil {
	public static Subject login(String configFile, String userName, String password) {
		// 读取shiro.ini文件, 获取SecurityManager工厂
		Factory<SecurityManager> factory = new IniSecurityManagerFactory(configFile);

		// 获取securityManager实例
		SecurityManager securityManager = factory.getInstance();

		// 把securityManager绑定到SecurityUtils进行预处理
		SecurityUtils.setSecurityManager(securityManager);

		// 获取当前用户
		Subject currentUser = SecurityUtils.getSubject();

		// 创建用户名/密码的令牌Token
		UsernamePasswordToken token = new UsernamePasswordToken(userName, password);

		// 身份认证, 通过源码知道这里有可能抛出异常
		try {
			currentUser.login(token);
			System.out.println("身份认证成功!");
		} catch (AuthenticationException e) {
			e.printStackTrace();
			System.out.println("身份认证失败!");
		}

		// 返回当前登录的用户
		return currentUser;
	}
}

三、创建基于角色的.ini配置文件(这里只做静态数据验证, 没有到数据库中取数)

shiro_role.ini, 固定写法,用户名 = 密码, 角色1, 角色2, 角色3 。。。

比如以下写法表示:java1234/123456这个用户同时拥有role1和role2的角色, 而jack/123这个用户只有role1这个角色

[users]
java1234 = 123456, role1, role2
jack = 123, role1

四、测试代码, 创建com.java1234.shiro.RoleTest

package com.java1234.shiro;

import org.apache.shiro.subject.Subject;
import org.junit.Test;
import com.java1234.common.ShiroUtil;

public class RoleTest {
	@Test
	public void testHasRole() {
		Subject currentUser = ShiroUtil.login("classpath:shiro_role.ini", "jack", "123");
		System.out.println(currentUser.hasRole("role1") ? "有role1这个角色" : "没有role1这个角色");
		System.out.println(currentUser.hasRole("role2") ? "有role2这个角色" : "没有role2这个角色");
	}
}

五、测试结果:

测试一:hasRole()

   

测试二:hasRoles()

boolean []result = currentUser.hasRoles(Arrays.asList("role1", "role2", "role3"));
System.out.println(result[0] ? "有role1这个角色" : "没有role1这个角色");
System.out.println(result[1] ? "有role2这个角色" : "没有role2这个角色");
System.out.println(result[2] ? "有role3这个角色" : "没有role3这个角色");

结果:

    

测试三:hasAllRoles()

boolean result = currentUser.hasAllRoles(Arrays.asList("role1", "role2"));
System.out.println(result ? "同时用拥有role1、role2" : "role1、role2角色不全有"); 

测试结果:

    

如果换成java1234/123456用户,测试结果:

    

测试四:checkRole(), 此方法没有返回值, 如果有指定的角色, 那么不报错, 如果在指定的角色中至少一个角色没有, 那么就会报错。

currentUser.checkRole("role1");  // currentUser.checkRole("role2");

结果:

    

currentUser.checkRole("role3");

结果:

    

测试五: checkRoles(), 判断集合, 如果指定的角色集合元素全部都有, 那么不会报错, 如果至少有一个没有, 那么就会报错!

currentUser.checkRoles(Arrays.asList("role1", "role2"));

结果:

    

currentUser.checkRoles(Arrays.asList("role1", "role2", "role3"));

结果:

    

    

--------------------------------------------

(2)基于权限的权限认证

1. shiro_permission.ini:

src/main/resources下创建基于权限认证的ini, 固定写法, 以下表示:

用户java1234/123456同时拥有role1和role2两个角色, jack/1234这个用户只有role1这个角色

role1这个角色只有user:select这个权限, role2这个角色同时拥有 user:add, user:update, user:delete 这三种权限。

[users]
java1234 = 123456, role1, role2
jack = 1234, role1
[roles]
role1 = user:select
role2 = user:add, user:update, user:delete

2. PermissionTest.java

测试1:currentUser.isPermitted(String param)

package com.java1234.shiro;

import org.apache.shiro.subject.Subject;
import org.junit.Test;
import com.java1234.common.ShiroUtil;

public class PermissionTest {
	@Test
	public void testIsPermitted() {
		Subject currentUser = ShiroUtil.login("classpath:shiro_permission.ini", "java1234", "123456");
		// 此方法一般不要使用接口参数, 使用字符串接收即可
		System.out.println(currentUser.isPermitted("user:select") ? "有user:select这个权限" : "没有user:select这个权限");
		System.out.println(currentUser.isPermitted("user:add") ? "有user:add这个权限" : "没有user:add这个权限");
		System.out.println(currentUser.isPermitted("user:update") ? "有user:update这个权限" : "没有user:update这个权限");
		System.out.println(currentUser.isPermitted("user:delete") ? "有user:delete这个权限" : "没有user:delete这个权限");
		System.out.println(currentUser.isPermitted("user:XXX") ? "有user:XXX这个权限" : "没有user:XXX这个权限");
	}
}

结果:

    

换成jack/1234用户,再测试:

    

测试2:currentUser.isPermitted(String ... params)

 

boolean []result = currentUser.isPermitted("user:select", "user:add", "user:update", "user:delete", "user:XXX");
		System.out.println(result[0] ? "有user:select权限" : "没有user:select权限");
		System.out.println(result[1] ? "有user:add权限" : "没有user:add权限");
		System.out.println(result[2] ? "有user:update权限" : "没有user:update权限");
		System.out.println(result[3] ? "有user:delete权限" : "没有user:delete权限");
		System.out.println(result[4] ? "有user:XXX权限" : "没有user:XXX权限");

结果:

    

换成jack用户再测试:

    

测试3:currentUser.isPermittedAll(String ... params), 使用java1234/123456用户测试

 

boolean result1 = currentUser.isPermittedAll("user:select", "user:add");
		boolean result2 = currentUser.isPermittedAll("user:select", "user:add", "user:XXX");
		System.out.println(result1 ? "指定的权限全都有" : "指定的权限不全有");
		System.out.println(result2 ? "指定的权限全都有" : "指定的权限不全有");

结果:

    

测试4:checkPermission(),判断单个权限, 其他方法类似,请查找 api 进行使用

/**
		 * 测试4:单个权限的判断
		 */
		currentUser.checkPermission("user:select");		// 如果有这个权限, 那么不会报错
		currentUser.checkPermission("user:XXX");		// 没有这个权限, 会报错

 

posted @ 2017-05-06 12:34  半生戎马,共话桑麻、  阅读(155)  评论(0)    收藏  举报
levels of contents