shiro在项目中的使用(二)

在第一部分,使用shiro主要做了基于url的登陆拦截,但是在真正的生产环境下往往是注解,标签等综合使用,以下是基于注解和标签的代码笔记

URL拦截权限控制是基于过滤器或者拦截器的
方法注解权限控制是基于代理(action代理)

【1】spring配置中开启shiro注解


    
        
        
    
    
    
    

注意:这里最好开启cglib代理(产生的是子类对象),默认是jdk代理(新的代理对象)

知识拓展:

1.JDK动态代理
此时代理对象和目标对象实现了相同的接口

2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,主要是对指定的类生成一个子类

具体查看:http://blog.csdn.net/cpzhong/article/details/6423333

另外注意:这里如果使用shiro了,在action中的baseAction就不能直接强转了,因为如果是jdk代理是action的新代理对象,而非action对象或者子类对象,所以强转会报错,这也是为什么要使用cglib代理的原因。

【2】方法上使用权限注解

/**
     * 删除派遣员
     * @return
     */
    @RequiresPermissions(value="staff11")//执行当前方法需要具有staff权限
    //@RequiresRoles(value="staff")//执行当前方法需要具有staff角色
    public String delete(){
        staffService.deleteBatch(ids);
        /**
         * 当权限或者角色任意一个不满足都会抛出org.apache.shiro.authz.UnauthorizedException: 
         * 异常,所以需要我们做公共异常捕获,在struts配置文件中配置公共异常捕获页面
         */
        return "list";
    }

【3】Realm中授权
在bosReaml的授权方法中授予相应权限

/**
     * 授权方法(这个用户有什么权限)
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("进入授权方法... ...");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermission("staff");//为当前用户授予staff权限
        
        //TODO 根据当前登录用户查询数据库,获取其对应的权限数据
        
        return info;
    }

【4】访问查看
(当授权是staff11是会正常操作删除方法,当授权非staff11时,我们分别授权staff11和staff,发现staff会报错,抛出异常org.apache.shiro.authz.UnauthorizedException)

shiro在项目中的使用(二)_第1张图片
2017-08-24_114226.png

当shiro使用注解时,遇到权限和角色不足时均会抛出org.apache.shiro.authz.UnauthorizedException异常,所以这里需要捕获处理
【5】struts中配置全局异常处理


            /login.jsp
            /unauthorizedUrl.jsp
        
        
         
        
            
        
shiro在项目中的使用(二)_第2张图片
2017-08-24_114617.png

修改后

shiro在项目中的使用(二)_第3张图片
2017-08-24_114957.png

使用标签进行资源控制
【1】jsp页面引入shiro标签

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>  

【2】对需要权限拦截的菜单 按钮进行拦截添加
这里主要shiro标签可以直接包html代码,也可以直接包js代码

//工具栏(给删除安全添加权限拦截)
    var toolbar = [ {
        id : 'button-view', 
        text : '查询',
        iconCls : 'icon-search',
        handler : doView
    }, {
        id : 'button-add',
        text : '增加',
        iconCls : 'icon-add',
        handler : doAdd
    }, {
        id : 'button-delete',
        text : '作废',
        iconCls : 'icon-cancel',
        handler : doDelete
    },{
        id : 'button-save',
        text : '还原',
        iconCls : 'icon-save',
        handler : doRestore
    }];

注意:表示只有拥有staff11权限的用户才会显示该按钮

前后对比

shiro在项目中的使用(二)_第4张图片
2017-08-24_115649.png
shiro在项目中的使用(二)_第5张图片
2017-08-24_115611.png

【通过查询数据库,进行用户授权】
修改自定义Realm的授权方法

/**
     * 授权方法(这个用户有什么权限)
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("进入授权方法... ...");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //info.addStringPermission("staff");//为当前用户授予staff权限
        //info.addRole("staff");//为当前用户授予staff角色(角色是权限的集合)  
        
        //TODO 根据当前登录用户查询数据库,获取其对应的权限数据
        //获取当前用户
        User user = (User) principals.getPrimaryPrincipal();
        List list = null;
        if(user.getUsername().equals("admin")){
            //超级管理员(查询所有权限)
            list = functionDao.findAll();
        }else{
            //普通用户(查询拥有权限)
            list = functionDao.findListByuserId(user.getId());
        }
        
        //授权
        for(Function function : list){
            info.addStringPermission(function.getCode());
        }
        return info;
    }

你可能感兴趣的:(shiro在项目中的使用(二))