您的位置:首页 > 其它

shiro 权限框架自定义Realm

2016-09-10 18:14 288 查看

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解析权限字符串,校验是否匹配

源码下载地址:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: