首先看先自定义的Realm:
-
/**
-
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
-
*/
-
@Override
-
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
-
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
-
//获取用的id
-
String userId = ((User)principals.getPrimaryPrincipal()).getUserId();
-
//查询对应用户的角色集合
扫描二维码关注公众号,回复: 2729010 查看本文章 -
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" %>
下面是我的权限表的大致结构:
下载地址:http://download.csdn.net/download/qq_38665235/9999509
这是Realm的下载地址:
下载地址:http://download.csdn.net/download/qq_38665235/9999496
转自https://blog.csdn.net/qq_38665235/article/details/78122298