第八讲 shiro位操作算法实现权限匹配(金庭波 QQ:14280784)

     《跟我学shiro》的第28页到30页,写得是使用位操作算法实现权限匹配,但是在验验过程中初学者会做得不太顺利,原因是教材中的代码不全。为了通俗易懂,我把这个实验过程全部笔录一遍,并说明原理。

先来认识几个单词:

authorizer        【奥得ruai热】  [经] 核准人,授权人,       在shiro中它是授权API的入口。

permission       【拍米生】       允许;批准,正式认可,认可,    在shiro中,它就是最后要得到的权限。
resolver            【瑞肉喂】       下决心者,解决[答]问题者;溶媒;求解仪。

PermissionResolver    在shiro中,它是根据通配符解析成权限。

RolePermissionResolver    在shiro它是根据角色解析成权限。


    第一步:新建一个shiro_6的maven工程;

    第二步:修改成UTF-8编码;

    第三步:写pom.xml,内容如下:

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>0.2.23</version>
		</dependency>
	</dependencies>

第四步:写src/main/resource下写shiro的配置文件:shiro.ini,内容如下:

[main]
#授权入口
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer

#采用解析Bit字符串得到权限
permissionResolver=www.jintingbo.com.BitAndWildPermissionResolver
authorizer.permissionResolver=$permissionResolver

#根据角色得到角色的权限
rolePermissionResolver=www.jintingbo.com.MyRolePermissionResolver
authorizer.rolePermissionResolver=$rolePermissionResolver

securityManager.authorizer=$authorizer

realm=www.jintingbo.com.MyRealm
securityManager.realms=$realm

第五步:写BitAndWildPermissionResolver类

    看上面的配置,因为这个类不是shiro内部有的,所以要自己写。代码如下:

public class BitAndWildPermissionResolver implements PermissionResolver {

	public Permission resolvePermission(String permissionString) {
		if (permissionString.startsWith("+")) {
			return new BitPermission(permissionString);
		}
		return new WildcardPermission(permissionString);
	}

}

注意这个类中有一个BitPermission类也可自己写。代码如下:

public class BitPermission implements Permission {

	private String resourceIdentify;
	private int permissionBit;
	private String instanceId;

	public BitPermission(String permissionString) {
		String[] array = permissionString.split("\\+");
		if (array.length > 1) {
			resourceIdentify = array[1];
		}
		if (StringUtils.isEmpty(resourceIdentify)) {
			resourceIdentify = "*";
		}
		if (array.length > 2) {
			permissionBit = Integer.valueOf(array[2]);
		}
		if (array.length > 3) {
			instanceId = array[3];
		}
		if (StringUtils.isEmpty(instanceId)) {
			instanceId = "*";
		}
	}
	public boolean implies(Permission p) {      //判断权限匹配
		if (!(p instanceof BitPermission)) {
			return false;
		}
		BitPermission other = (BitPermission) p;
		if (!("*".equals(this.resourceIdentify) || this.resourceIdentify
				.equals(other.resourceIdentify))) {
			return false;
		}
		if (!(this.permissionBit == 0 || (this.permissionBit & other.permissionBit) != 0)) {
			return false;
		}
		if (!("*".equals(this.instanceId) || this.instanceId
				.equals(other.instanceId))) {
			return false;
		}
		return true;
	}

}

第六步:写MyRolePermissionResolver类    

public class MyRolePermissionResolver implements RolePermissionResolver {

    public Collection<Permission> resolvePermissionsInRole(String roleString) {
        if("role1".equals(roleString)) {
            return Arrays.asList((Permission)new WildcardPermission("menu:*"));
        }
        return null;
    }

}

第七步:写MyRealm,这一部分,教材上的代码不全,所以在这里加上它的验证部分。

public class MyRealm extends org.apache.shiro.realm.AuthorizingRealm {

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); 
		authorizationInfo.addRole("role1"); 
		authorizationInfo.addRole("role2"); 
		authorizationInfo.addObjectPermission(new BitPermission("+user1+10")); 
		authorizationInfo.addObjectPermission(new WildcardPermission("user1:*")); 
		authorizationInfo.addStringPermission("+user2+10"); 
		authorizationInfo.addStringPermission("user2:*");
		return authorizationInfo; 
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		String username = (String)token.getPrincipal();  //得到用户名
		String password = new String((char[])token.getCredentials()); //得到密码
		if(!"zhang".equals(username)) { 
		throw new UnknownAccountException(); //如果用户名错误
		} 
		if(!"123".equals(password)) { 
		throw new IncorrectCredentialsException(); //如果密码错误
		} 
		//如果身份认证验证成功,返回一个 AuthenticationInfo 实现;
		return new SimpleAuthenticationInfo(username, password, getName()); 
	}
	
	public String getName() {
		return "aaa";
	}

	public boolean supports(AuthenticationToken arg0) {
		return arg0 instanceof UsernamePasswordToken;
	}	

}

第八步:写测试运行的类

public class MyTest {

private static void login(String configFile,String username,String password) { 
//1、获取 SecurityManager 工厂,此处使用 Ini 配置文件初始化 SecurityManager 
Factory<org.apache.shiro.mgt.SecurityManager> factory = 
new IniSecurityManagerFactory(configFile); 
//2、得到 SecurityManager 实例  并绑定给 SecurityUtils 
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); 
SecurityUtils.setSecurityManager(securityManager); 
//3、得到 Subject 及创建用户名/密码身份验证 Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject(); 
UsernamePasswordToken token = new UsernamePasswordToken(username,password); 
subject.login(token); 


public static void main(String[] args) {
login("classpath:shiro.ini","zhang","123");
Subject subject = SecurityUtils.getSubject();
try{
subject.isPermitted("system:menu111:view");
System.out.println("OK!");
}catch (UnauthorizedException e){
System.out.println("没有这个权限!");
}

}

}

第九步:运行

完毕

QQ:14280784 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庭博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值