shiro授权认证理解

工程目录:


创建shiro-realm.ini:

[main]
#\u81ea\u5b9a\u4e49 realm
customRealm=cn.itcast.shiro.realm.CustomRealm
#\u5c06realm\u8bbe\u7f6e\u5230securityManager\uff0c\u76f8\u5f53 \u4e8espring\u4e2d\u6ce8\u5165
securityManager.realms=$customRealm

创建自定义的customRealm:

package cn.itcast.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{


@Override
public void setName(String name){
super.setName("customRelam");
}




@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
// token是用户输入的
//第一步从token中取出身份信息
String userCode = (String) token.getPrincipal();
System.out.println("userCode:"+userCode);
//第二步:根据用户输入的userCode从数据库中查询
//...
//模拟从数据库查询密码
String password = "111111";
//如果查询不到返回null
//如果查询到返回认证信息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> permissions = new ArrayList<String>();
permissions.add("user:create");//用户的创建
permissions.add("items:add");//商品添加权限
// 。。。
// 查到权限数据,返回授权信息(要包括上面的permissions)
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
// 将上边查询到授权信息填充到simpleAuthenticationInfo对象中
simpleAuthorizationInfo.addStringPermissions(permissions);
return simpleAuthorizationInfo;
}
}

创建测试用例:

package cn.itcast.shiro.authorization;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Test;


public class authorizationTest {

//角色、资源权限控制
@Test
public void testAuthorizationCustomRealm(){
//创建securityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
"classpath:shiro-realm.ini");

SecurityManager securityManager = factory.getInstance();

SecurityUtils.setSecurityManager(securityManager);

//创建subject
Subject subject = SecurityUtils.getSubject();

UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "111111");
//执行认证
try {
subject.login(token);
} catch (AuthenticationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("authorizationTest.testAuthorization()"+subject.isAuthenticated());

// 认证通过授权
boolean isPermitted = subject.isPermitted("user:create:1");
System.out.println("单个权限判断"+isPermitted);

/* boolean isHasRole = subject.hasRole("role1");
System.out.println("单个权限判断"+isHasRole);*/
/*boolean[] isPermitteAll = subject.isPermitted("user:create:1","user:create");*/
boolean isPermitteAll = subject.isPermittedAll("user:create:1","user:create");
System.out.println("isPermitteAll:"+isPermitteAll);
subject.checkPermission("items:add:1");

}
}

授权的流程:

1.subject进行授权,调用方法isPermitted("permission串");

2.SecurityManager执行授权,通过ModularRealmAuthorizer执行授权

3.ModularRealmAuthorizer执行realm(自定义的Custom)从数据库查询权限数据调用realm的授权方法:doGetAuthorizationInfo

4.realm从数据库查询权限数据,返回ModularRealmAuthorizer

5.ModularRealmAuthorizer调用PermissionResolver进行权限串比对

6.如果比对后,isPermitted中“permission串”在realm查询到权限数据中,说明用户访问permission串有权限,否则,没有权限,抛出异常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章