shiro 权限框架自定义Realm

1.shiro提供的realm


最基础的是Realm接口,CachingRealm负责缓存处理,AuthenticationRealm负责认证,AuthorizingRealm负责授权,通常自定义的realm继承AuthorizingRealm。

1.1  创建java工程

jdk版本:1.7.0_72
eclipse:elipse-indigo

1.2 加入shiro-core的Jar包及依赖包


1.3在项目下创建config 包,然后添加log4j.properties日志配置文件以及shiro-realm.ini 文件

log4j 文件内容

log4j.rootLogger=debug, stdout
 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
shiro-realm.ini 文件内容
[main]
#自定义 realm
customRealm=cn.itcast.shiro.authentication.realm.CustomRealm1
#realm设置到securityManager
securityManager.realms=$customRealm

1.4 认证自定义Realm 代码

public class CustomRealm1 extends AuthorizingRealm {

	@Override
	public String getName() {
		return "customRealm1";
	}

	//支持UsernamePasswordToken
	@Override
	public boolean supports(AuthenticationToken token) {
		return token instanceof UsernamePasswordToken;
	}

	//认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		
		//从token中 获取用户身份信息
		String username = (String) token.getPrincipal();
		//拿username从数据库中查询
		//....
		//如果查询不到则返回null
		if(!username.equals("zhang")){//这里模拟查询不到
			return null;
		}
		
		//获取从数据库查询出来的用户密码 
		String password = "123";//这里使用静态数据模拟。。
		
		//返回认证信息由父类AuthenticatingRealm进行认证
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
				username, password, getName());

		return simpleAuthenticationInfo;
	}

	//授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		// TODO Auto-generated method stub
		return null;
	}

}

1.5 测试代码

@Test
	public void testCustomerAuthenticationRealm()
	{
	// 构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境
	Factory<org.apache.shiro.mgt.SecurityManager> factoty  = new IniSecurityManagerFactory
	("classpath:shiro-realm.ini");
			
				// 通过工厂创建SecurityManager
				SecurityManager securityManager = factoty.getInstance();
				
				// 将securityManager设置到运行环境中
				SecurityUtils.setSecurityManager(securityManager);
				
				// 创建一个Subject实例,该实例认证要使用上边创建的securityManager进行
				Subject subject = SecurityUtils.getSubject();
				
				// 创建token令牌,记录用户认证的身份和凭证即账号和密码 
				UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
				
				try {
					subject.login(token);
				} catch (AuthenticationException e) {
					e.printStackTrace();
				}
				boolean authenticated = subject.isAuthenticated();
				
				System.out.println("用户认证状态"+authenticated);
	}


1.6 授权自定义Realm 代码

// 授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		// 获取身份信息
		String username = (String) principals.getPrimaryPrincipal();
		// 根据身份信息从数据库中查询权限数据
		//....这里使用静态数据模拟
		List<String> permissions = new ArrayList<String>();
		permissions.add("user:create");
		permissions.add("user.delete");
		
		//将权限信息封闭为AuthorizationInfo
		
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		for(String permission:permissions){
			simpleAuthorizationInfo.addStringPermission(permission);
		}
		
		return simpleAuthorizationInfo;
	}

1.7 测试代码

@Test
	public void testCustomerAuthorizationRealm()
	{
		// 构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境
				Factory<org.apache.shiro.mgt.SecurityManager> factoty  = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
			
				// 通过工厂创建SecurityManager
				SecurityManager securityManager = factoty.getInstance();
				
				// 将securityManager设置到运行环境中
				SecurityUtils.setSecurityManager(securityManager);
				
				// 创建一个Subject实例,该实例认证要使用上边创建的securityManager进行
				Subject subject = SecurityUtils.getSubject();
				
				// 创建token令牌,记录用户认证的身份和凭证即账号和密码 
				UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
				
				try {
					subject.login(token);
				} catch (AuthenticationException e) {
					e.printStackTrace();
				}
				boolean authenticated = subject.isAuthenticated();
				
				System.out.println("用户认证状态"+authenticated);
				

				// 基于资源的授权,调用isPermitted方法会调用CustomRealm从数据库查询正确权限数据
				// isPermitted传入权限标识符,判断user:create:1是否在CustomRealm查询到权限数据之内
				boolean permitted = subject.isPermitted("user:create:1");
				System.out.println("单个权限的判断:"+permitted);
				
				boolean permittedAll = subject.isPermittedAll("user:create","item:add");
				System.out.println("多个权限的判断:"+permittedAll);
				
				// 使用check方法进行授权,如果授权不通过会抛出异常
				subject.checkPermission("items:add:1");
				
	}

1.7 授权执行流程

1、	执行subject.isPermitted("user:create")
2、	securityManager通过ModularRealmAuthorizer进行授权
3、	ModularRealmAuthorizer调用realm获取权限信息
4、	ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

源码下载地址:点击打开链接

猜你喜欢

转载自blog.csdn.net/u012014505/article/details/52496238