shiro學習:shiro實現授權

我的上一篇:shiro實現登錄和退出 已經實現了登錄和退出功能,這篇簡單的實現一些用戶的授權。
爲什麼使用shiro基於資源的權限控制:
基於角色的權限控制:根據角色判斷是否有操作權限,因爲角色的變化 性較高,如果角色修改需要修改控制代碼,系統可擴展性不強。
基於資源的權限控制:根據資源權限判斷是否有操作權限,因爲資源較爲固定,如果角色修改或角色中權限修改不需要修改控制代碼,使用此方法系統可維護性很強。建議使用。
一、授權的流程
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進行授權(完整的realm,請參考上一篇)
        //用於授權
	//Authorization 授權的意思
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//從 principals獲取主身份信息
		//將getPrimaryPrincipal方法返回值轉爲真實身份類型(在上邊的doGetAuthenticationInfo認證通過填充到SimpleAuthenticationInfo中身份類型),
		ActiveUser activeUser =  (ActiveUser) principals.getPrimaryPrincipal();
		// 根據身份信息獲取權限信息
		// 從數據庫獲取到權限數據
		List<SysPermission> permissionList = null;
		try {
			permissionList = sysService.findPermissionListByUserId(activeUser.getUserid());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 單獨定一個集合對象
		List<String> permissions = new ArrayList<String>();
		if (permissionList != null) {
			for (SysPermission sysPermission : permissionList) {
				// 將數據庫中的權限標籤 符放入集合
				permissions.add(sysPermission.getPercode());
			}
		}

		// 查到權限數據,返回授權信息(要包括 上邊的permissions)
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		// 將上邊查詢到授權信息填充到simpleAuthorizationInfo對象中
		simpleAuthorizationInfo.addStringPermissions(permissions);

		return simpleAuthorizationInfo;
	}
三、使用註解方式進行授權
3.1在springmvc中配置,開啓aop;修改springmvc的配置文件
<!-- 開啓aop,對類代理 -->
	<aop:config proxy-target-class="true"></aop:config>
	<!-- 開啓shiro註解支持 -->
	<bean
		class="
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" />
	</bean>

3.2創建一個Controller
在Controller的方法中加入對應的權限註解:例如@RequiresPermissions("item:query") shiro會與器進行匹配,如果沒有權限會報出異常
@Controller
@RequestMapping("items")
public class ItemController {

	@Resource
	private ItemsService itemServiceImpl;
	
	@RequestMapping("queryItems.do")
	@RequiresPermissions("item:query")
	public ModelAndView queryItems(HttpServletRequest request) throws Exception{
		
		//String id = request.getParameter("id");
		List<ItemsCustom> itemList = itemServiceImpl.findItemsList(null);
		ModelAndView mv = new ModelAndView();
		mv.addObject("itemList", itemList);
		// 指定邏輯視圖名
		mv.setViewName("itemsList");
		return mv;
	}
}
沒有權限,不能跳轉到指定頁面問題:
我們雖然已經在shiro的配置文件中配置了
<!-- 通過unauthorizedUrl指定沒有權限操作時的權限頁面 -->
		<property name="unauthorizedUrl" value="/refuse.jsp" />
但是,我們會發現,如果我們沒有權限的時候,不會跳轉到refuse.jsp中
原因
這是因爲shiro源代碼中判斷了filter是否爲AuthorizationFilter,只有perms,roles,ssl,rest,port纔是屬於AuthorizationFilter,而anon,authcBasic,auchc,user是AuthenticationFilter,所以unauthorizedUrl設置後不起作用
解決方法:
配置自定義的異常處理器,在異常處理器中加入
if(ex instanceof CustomException){
			customException = (CustomException)ex;
		}else if(ex instanceof UnauthorizedException){
			customException = new CustomException("沒有權限");
		}else{
			//針對非CustomException異常,對這類重新構造成一個CustomException,異常信息爲“未知錯誤”
			customException = new CustomException("未知錯誤");
		}




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