shiro真正項目中的實戰應用核心代碼!!!
歡迎轉載!!!請註明出處!!!
說道shiro的學習之路真是相當坎坷,網上好多人發的帖子全是簡單的demo樣例,核心代碼根本沒有,在學習過程中遇到過N多坑。
經過自己的努力,終於整出來了,等你整明白之後發現,確實沒那麽難,只是沒人告訴你,自己去想向確實不好辦,只能通過看源碼加上自己猜想,不斷嘗試。
直接看主題。我就直接說受權這了,不說認證登錄了,這種帖子n多個,我要說的是真正的核心代碼!!!含金量超高!!!歡迎轉載!請註明出處!!!
首先看先自定義的Realm:
/** * 授權查詢回調函數, 進行鑒權但緩存中無用戶的授權信息時調用. */ @Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //獲取用的id String userId = ((User)principals.getPrimaryPrincipal()).getUserId(); //查詢對應用戶的角色集合 List<RoleR> roleList=userService.getRoleList(userId); List<Menu> menuList=null; List<String> roleAllList = new ArrayList<String>(); List<String> resourceList = new ArrayList<String>(); for (RoleR role : roleList) { roleAllList.add(role.getRoleId()+""); //查詢對應角色的對應權限集合 menuList=userService.getMenuList(role.getRoleId());for (Menu menu : menuList) { if(StringUtils.isNotBlank(menu.getPermission())){ resourceList.add(menu.getPermission()); } } } //賦角色 info.addRoles(roleAllList); //賦權限 info.addStringPermissions(resourceList); return info; }
可能都見過這個方法,但是你們知道什麽時候調用嗎?
我來揭秘:
@RequestMapping("getProductList") @ResponseBody @RequiresPermissions("product:list")//這是是核心 public String getProductList(Integer offset,Integer limit,Product product){ page.setStrat(offset); page.setPagecount(limit); page.setObj(product); productService.getProductList(page); Map map=new HashMap(); map.put("total", page.getPagesumcount()); map.put("rows", page.getList()); Gson gson=new Gson(); String str=gson.toJson(map); return str; }
只要你訪問後臺的方法上面有 @RequiresPermissions 這個註解,那麽此時shiro回去訪問 doGetAuthorizationInfo
這個方法,然後回去驗證當前用戶是否有次權限,如果沒有就回拋會授權異常
但是用戶是看不到的,怎麽辦?這時候就要用另外一個方法,進行全局異常捕獲。
沒錯就是用
@ControllerAdvice和@ExceptionHandler(value={UnauthorizedException.class})
@ResponseStatus(HttpStatus.UNAUTHORIZED)這些註解結合使用。用來捕獲所有控制層拋來的制定異常
然後在轉到制定的錯誤提示頁面提示用戶相關錯誤信息,如果你們用了aop攔截了controller並且是環繞通知,這時候有個坑,是捕獲不到錯誤的。
/** * 沒有權限 異常 * <p/> * 後續根據不同的需求定制即可 */ @ExceptionHandler(value={UnauthorizedException.class}) @ResponseStatus(HttpStatus.UNAUTHORIZED) public ModelAndView processUnauthenticatedException(NativeWebRequest request, UnauthorizedException e){ System.out.println("-----------------------------------------------------"); ModelAndView mv = new ModelAndView(); mv.addObject("errorInfo", e); mv.setViewName("unauthorized"); return mv; }
原因因為aop攔截後拋出了更大的異常,而你捕獲的是未授權,所以要重新拋出未授權
不僅僅是權限控制,也可以角色控制,一樣的用法
<div id="toolbar" class="btn-group"> <shiro:hasPermission name="product:insert"> <button id="btn_add" type="button" class="btn btn-primary" onclick="addProduct()"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增 </button> </shiro:hasPermission> <shiro:hasPermission name="product:deletes"> <button id="btn_delete" type="button" class="btn btn-warning" onclick="delProductAll()"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>刪除 </button> </shiro:hasPermission> <shiro:hasPermission name="product:insert"> <button id="btn_delete" type="button" class="btn btn-success" onclick="updateAllProduct()"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>批量修改圖片 </button> </shiro:hasPermission> <shiro:hasPermission name="product:excel"> <button id="btn_delete" type="button" class="btn btn-success" onclick="exportExcel()"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>導出Excel </button> </shiro:hasPermission> <shiro:hasPermission name="product:xml"> <button id="btn_delete" type="button" class="btn btn-success" onclick="exportXml()"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>導出Xml </button> </shiro:hasPermission> </div>
如果當前用戶符合這些權限,按鈕就可以顯示,前天要引入shiro標簽庫
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
下面是我的權限表的大致結構:
下載地址:http://download.csdn.net/download/qq_38665235/9999509
這是Realm的下載地址:
下載地址:http://download.csdn.net/download/qq_38665235/9999496
shiro真正項目中的實戰應用核心代碼!!!