shiro(四)

 授权

一,授权概念

        授权,也叫访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等)。在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限(Permission)、角色(Role)。

二,授权方式

Shiro支持三种方式的授权:

 编程式:通过写if/else授权代码块完成: 

Java代码   收藏代码
  1. Subject subject = SecurityUtils.getSubject();  
  2. if(subject.hasRole(“admin”)) {  
  3.     //有权限  
  4. else {  
  5.     //无权限  
  6. }   

 

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

Java代码   收藏代码
  1. @RequiresRoles("admin")  
  2. public void hello() {  
  3.     //有权限  
  4. }   

没有权限将抛出相应的异常;

 

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

Java代码   收藏代码
  1. <shiro:hasRole name="admin">  
  2. <!— 有权限 —>  
  3. </shiro:hasRole>   

三,授权

1、在ini配置文件配置用户拥有的角色和角色对应的权限(shiro-permission.ini) 

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

	// 角色授权,资源授权
	@Test
	public void TestAuthorization() {

		// 创建securityManager工厂,通过ini配置文件创建securityManager工厂
		Factory<SecurityManager> factory = new IniSecurityManagerFactory(
				"classpath:shiro-permission.ini");

		// 创建SecurityManager
		SecurityManager securityManager = factory.getInstance();

		// 将securityManager设置当前的运行环境中(单例模式)
		SecurityUtils.setSecurityManager(securityManager);

		// 从SecurityUtils里边创建一个subject
		Subject subject = SecurityUtils.getSubject();

		// 在认证提交前准备token(令牌)
		// 这里的账号和密码 将来是由用户输入进去
		UsernamePasswordToken token = new UsernamePasswordToken("lisi","123");

		try {
			// 执行认证提交
			subject.login(token);
		} catch (AuthenticationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 是否认证通过
		boolean isAuthenticated = subject.isAuthenticated();

		System.out.println("是否认证通过:" + isAuthenticated);
		//基于角色的授权
		//hasRole传入角色唯一标识
		boolean hasRole=subject.hasRole("role1");
		System.out.println("是否拥有该角色:"+hasRole);
		//基于多个角色的判断
		boolean hasRoles=subject.hasAllRoles(Arrays.asList("role1","role2","role3"));
		System.out.println("是否拥有多个角色:"+hasRoles);
		//使用check进行授权,若不通过抛出异常
		 subject.checkRoles("role4");
		//基于资源的授权
		boolean isPermitted=subject.isPermitted("user:create");
		System.out.println("是否可以操作该资源:"+isPermitted);
		//对多个资源权限进行判断
		boolean isPermittedAll=subject.isPermittedAll("user:create:1","user:update:1");
		System.out.println("对多个资源权限进行判断:"+isPermittedAll);
		//使用check进行授权,若不通过抛出异常
		subject.checkPermission("user:delete");
	}

权限标识符号规则:资源:操作:实例(中间使用半角:分隔)

usercreate:01  表示对用户资源的01实例进行create操作。

user:create:表示对用户资源进行create操作,相当于user:create:*,对所有用户资源实例进行create操作。

 user*01  表示对用户资源实例01进行所有操作。

四,自定义realm进行授权

   1)1、在ini配置文件配置用户拥有的角色和角色对应的权限(shiro-relam.ini) 

#自定义 realm
customRealm=com.example.shiro.realm.CustomRealm
#将realm设置到securityManager,相当 于spring中注入
securityManager.realms=$customRealm

       2)自定义的realm

package com.example.shiro.realm;

import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;


public class CustomRealm extends AuthorizingRealm {

	// 设置realm的名称
	@Override
	public void setName(String name) {
		super.setName("customRealm");
	}

	// 用于认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {

		// token是用户输入的
		// 第一步从token中取出身份信息
		String userCode = (String) token.getPrincipal();
		//String username = (String)token.getPrincipal();  //得到用户名  
	   // String password = new String((char[])token.getCredentials()); //得到密码 

		// 第二步:根据用户输入的userCode从数据库查询
		// ....
	

		// 如果查询不到返回null
		//数据库中用户账号是zhangsansan
		/*if(!userCode.equals("zhangsansan")){//
			return null;
		}*/
		
		
		// 模拟从数据库查询到密码
		String password = "111111";

		// 如果查询到返回认证信息AuthenticationInfo

		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
				userCode, password, this.getName());

		return simpleAuthenticationInfo;
	}

	// 用于授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		String usercode=(String) principals.getPrimaryPrincipal();
		//模拟从数据库中获取了数据
		List<String> permission=new ArrayList<String>();
		permission.add("user:add");//用户的创建
		permission.add("user:update");//用户的修改
		SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
		//将从数据库中查到的信息放入simpleAuthorizationInfo中
		simpleAuthorizationInfo.addStringPermissions(permission);
		return simpleAuthorizationInfo;
	}

}

3)测试用例

// 自定义realm,资源授权测试
	@Test
	public void testCustomRealm() {

		// 创建securityManager工厂,通过ini配置文件创建securityManager工厂
		Factory<SecurityManager> factory = new IniSecurityManagerFactory(
				"classpath:shiro-realm.ini");

		// 创建SecurityManager
		SecurityManager securityManager = factory.getInstance();

		// 将securityManager设置当前的运行环境中
		SecurityUtils.setSecurityManager(securityManager);

		// 从SecurityUtils里边创建一个subject
		Subject subject = SecurityUtils.getSubject();

		// 在认证提交前准备token(令牌)
		// 这里的账号和密码 将来是由用户输入进去
		UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
				"111111");

		try {
			// 执行认证提交
			subject.login(token);
		} catch (AuthenticationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 是否认证通过
		boolean isAuthenticated = subject.isAuthenticated();

		System.out.println("是否认证通过:" + isAuthenticated);
		//基于角色的授权
				//hasRole传入角色唯一标识
				/*boolean hasRole=subject.hasRole("role1");
				System.out.println("是否拥有该角色:"+hasRole);*/
				//基于多个角色的判断
				/*boolean hasRoles=subject.hasAllRoles(Arrays.asList("role1","role2","role3"));
				System.out.println("是否拥有多个角色:"+hasRoles);*/
				//使用check进行授权,若不通过抛出异常
				// subject.checkRoles("role4");
				//基于资源的授权
				boolean isPermitted=subject.isPermitted("user:add");
				System.out.println("是否可以操作该资源:"+isPermitted);
				//对多个资源权限进行判断
				boolean isPermittedAll=subject.isPermittedAll("user:create:1","user:update:1");
				System.out.println("对多个资源权限进行判断:"+isPermittedAll);
				//使用check进行授权,若不通过抛出异常
				subject.checkPermission("user:delete");
	}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值