shiro真正專案中的實戰應用核心程式碼!!!
阿新 • • 發佈:2019-01-04
歡迎轉載!!!請註明出處!!!
說道shiro的學習之路真是相當坎坷,網上好多人發的帖子全是簡單的demo樣例,核心程式碼根本沒有,在學習過程中遇到過N多坑。
經過自己的努力,終於整出來了,等你整明白之後發現,確實沒那麼難,只是沒人告訴你,自己去想向確實不好辦,只能通過看原始碼加上自己猜想,不斷嘗試。
直接看主題。我就直接說受權這了,不說認證登入了,這種帖子n多個,我要說的是真正的核心程式碼!!!含金量超高!!!歡迎轉載!請註明出處!!!
首先看先自定義的Realm:
可能都見過這個方法,但是你們知道什麼時候呼叫嗎?/** * 授權查詢回撥函式, 進行鑑權但快取中無使用者的授權資訊時呼叫. */ @Override protected 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攔截後丟擲了更大的異常,而你捕獲的是未授權,所以要重新丟擲未授權
不僅僅是許可權控制,也可以角色控制,一樣的用法
接下來就是前臺js的許可權控制
<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" %>
下面是我的許可權表的大致結構:
這是Realm的下載地址: