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串有權限,否則,沒有權限,拋出異常。

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