shiro真正项目中的实战应用核心代码!!!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro真正项目中的实战应用核心代码!!!相关的知识,希望对你有一定的参考价值。

欢迎转载!!!请注明出处!!!

说道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拦截后抛出了更大的异常,而你捕获的是未授权,所以要重新抛出未授权

技术分享

不仅仅是权限控制,也可以角色控制,一样的用法

 

 

<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真正项目中的实战应用核心代码!!!的主要内容,如果未能解决你的问题,请参考以下文章

shiro实战系列之架构

shiro权限项目中的简单应用

shiro权限项目中的简单应用

springboot整合shiro

TypeScript 系统入门到项目实战

接口测试核心技能与框架实战