Shiro Review——自定义Realm实现授权
2016-06-10 10:59
555 查看
在自定义Realm中,可以进对数据库的查询,将认证后的用户的资源权限全部查询出来。
/**
* 自定义Realm
* @author LiuHuiChao
*
*/
public class CustomRealm extends AuthorizingRealm{
@Override
public void setName(String name) {
super.setName("customName");
}
/**
* 认证方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
//1,从token中取出用户身份信息
String userCode=(String)token.getPrincipal();
//2,根据用户输入的账号从数据库查询
String password="111111";//模拟从库里查询到的密码
//2--1,查询不到返回null
//2--2,查询到返回AuthenticationInfo
SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(userCode,password,this.getName());
return simpleAuthenticationInfo;
}
/**
* 授权方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
//从principals获取主身份信息
//将getPrimaryPrincipal方法返回值转换为真实身份类型,(在doGetAuthenticationInfo认证通过,填充到SimpleAuthenticationInfo中身份信息类型)
String userCode=(String) principals.getPrimaryPrincipal();
//根据身份信息,获取权限信息
//连接数据库。。。
//模拟从数据库获取到数据
List<String> permissionList=new ArrayList<String>();
permissionList.add("user:create");//用户的创建权限
permissionList.add("items:add");//商品添加权限
// and so on...
//查到权限数据,返回授权信息(把上面查询到的数据填充)
SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
//将上面查询到的授权信息进行填充
authorizationInfo.addStringPermissions(permissionList);
return authorizationInfo;
}
}
ini配置:
[main]
#自定义realm
customRealm=cn.itcast.shiro.realm.CustomRealm
#将realm设置到securityManager
securityManager.realms=$customRealm
测试授权:
/**
* 自定义realm进行测试
*/
@Test
public void testAuthorizationWithCustomRealm(){
//创建SecurityManager工厂
Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro-realm.ini");
//创建SecurityManager
SecurityManager securityManager=factory.getInstance();
//将SecurityManager设置到系统运行环境,和spring整合后将SecurityManager配置到spring容器中
SecurityUtils.setSecurityManager(securityManager);
//创建subject
Subject subject=SecurityUtils.getSubject();
//执行认证
UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123");
try {
subject.login(token);
} catch (AuthenticationException e) {
e.printStackTrace();
}
System.out.println("认证状态:"+subject.isAuthenticated());
/*基于资源的授权
*
* 调用isPermitted方法会调用自定义realm来查询权限数据
* */
boolean isPermitted=subject.isPermitted("user:create:1");
System.out.println("是否有user:create权限:"+isPermitted);
boolean isPremittedAll=subject.isPermittedAll("user:create","user:delete");
System.out.println("是否有user:create,user:delete权限:"+isPermitted);
//使用无返回值的check
try {
subject.checkPermission("user:post");
} catch (AuthorizationException e) {
System.out.println("用户没有user:post权限");
e.printStackTrace();
}
}
授权流程:
1、对subject进行授权,调用方法isPermitted("permission串")
2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
3、ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据
调用realm的授权方法:doGetAuthorizationInfo
4、realm从数据库查询权限数据,返回ModularRealmAuthorizer
5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对
6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。
/**
* 自定义Realm
* @author LiuHuiChao
*
*/
public class CustomRealm extends AuthorizingRealm{
@Override
public void setName(String name) {
super.setName("customName");
}
/**
* 认证方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
//1,从token中取出用户身份信息
String userCode=(String)token.getPrincipal();
//2,根据用户输入的账号从数据库查询
String password="111111";//模拟从库里查询到的密码
//2--1,查询不到返回null
//2--2,查询到返回AuthenticationInfo
SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(userCode,password,this.getName());
return simpleAuthenticationInfo;
}
/**
* 授权方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
//从principals获取主身份信息
//将getPrimaryPrincipal方法返回值转换为真实身份类型,(在doGetAuthenticationInfo认证通过,填充到SimpleAuthenticationInfo中身份信息类型)
String userCode=(String) principals.getPrimaryPrincipal();
//根据身份信息,获取权限信息
//连接数据库。。。
//模拟从数据库获取到数据
List<String> permissionList=new ArrayList<String>();
permissionList.add("user:create");//用户的创建权限
permissionList.add("items:add");//商品添加权限
// and so on...
//查到权限数据,返回授权信息(把上面查询到的数据填充)
SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
//将上面查询到的授权信息进行填充
authorizationInfo.addStringPermissions(permissionList);
return authorizationInfo;
}
}
ini配置:
[main]
#自定义realm
customRealm=cn.itcast.shiro.realm.CustomRealm
#将realm设置到securityManager
securityManager.realms=$customRealm
测试授权:
/**
* 自定义realm进行测试
*/
@Test
public void testAuthorizationWithCustomRealm(){
//创建SecurityManager工厂
Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro-realm.ini");
//创建SecurityManager
SecurityManager securityManager=factory.getInstance();
//将SecurityManager设置到系统运行环境,和spring整合后将SecurityManager配置到spring容器中
SecurityUtils.setSecurityManager(securityManager);
//创建subject
Subject subject=SecurityUtils.getSubject();
//执行认证
UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123");
try {
subject.login(token);
} catch (AuthenticationException e) {
e.printStackTrace();
}
System.out.println("认证状态:"+subject.isAuthenticated());
/*基于资源的授权
*
* 调用isPermitted方法会调用自定义realm来查询权限数据
* */
boolean isPermitted=subject.isPermitted("user:create:1");
System.out.println("是否有user:create权限:"+isPermitted);
boolean isPremittedAll=subject.isPermittedAll("user:create","user:delete");
System.out.println("是否有user:create,user:delete权限:"+isPermitted);
//使用无返回值的check
try {
subject.checkPermission("user:post");
} catch (AuthorizationException e) {
System.out.println("用户没有user:post权限");
e.printStackTrace();
}
}
授权流程:
1、对subject进行授权,调用方法isPermitted("permission串")
2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
3、ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据
调用realm的授权方法:doGetAuthorizationInfo
4、realm从数据库查询权限数据,返回ModularRealmAuthorizer
5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对
6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。
相关文章推荐
- Codevs 1065 01字符串
- Shiro Review——自定义Realm实现授权
- 关于C++中的临时对象问题
- 大道理
- Struts2使用OGNL和校验框架
- 每天一命令(5) rm (remove files or directories) 1分钟
- JAXB注解 java 关于xml的注解,自动生成xml文件 - @XML***
- 313. Super Ugly Number
- Linux开启之谜
- 客户端使用java,服务端使用c++的corba编程环境搭建
- 页面悬浮框
- ubuntu12.04修改键盘
- Linux常用命令
- Android Framework综述
- C++单例模式
- Android之GLES2.0显示立方体各面不同图片测试代码
- JS获取当前时间年月日时分秒
- 微信公众号每次调用接口正确或错误的返回码
- Linux下make机制
- iOS---UITextField代理方法解决键盘遮挡文本框