spring boot 前后端分离整合shiro(四)自定义Filter

平常我们做权限的时候会遇到这种情况:一个权限被多个角色拥有。比如我超级管理员可以添加用户,普通admin也可以添加用户,这是很正常很合理的。但是使用shiro的roles时有点小问题,下面测试一下:
新建一个JsonData类,用于规定返回的格式:

package com.example.demo.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * @author 黄豪琦
 * 日期:2019-07-03 13:51
 * 说明:用于返回
 */
@Data
public class JsonData implements Serializable {

    private static final long serialVersionUID = 7983993295462511394L;

    /**
     * 1 成功 0:处理中 -1:失败
     */
    private Integer code;
    private Object data;
    private String msg;

    public JsonData() {
    }

    public JsonData(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public JsonData(Integer code, Object data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    public static JsonData success(){
        return new JsonData(1, null, null);
    }

    public static JsonData success(Object data){
        return new JsonData(1, data, null);
    }

    public static JsonData success(String msg){
        return new JsonData(1, null, msg);
    }

    public static JsonData success(Object data, String msg){
        return new JsonData(1, data, msg);
    }

    public static JsonData success(Integer code){
        return new JsonData(code, null, null);
    }

    public static JsonData success(Integer code, Object data){
        return new JsonData(code, data, null);
    }
    public static JsonData success(Integer code, String msg){
        return new JsonData(code, null, msg);
    }
    public static JsonData success(Integer code, Object data, String msg){
        return new JsonData(code, data, msg);
    }

    public static JsonData error(){
        return new JsonData(-1, null, null);
    }

    public static JsonData error(String msg){
        return new JsonData(-1, null, msg);
    }
}

新增一个无权限跳转接口:

/**
 * @author 黄豪琦
 * 日期:2019-07-11 14:04
 * 说明:
 */
@RequestMapping("/pub")
@RestController
public class PubController {

    @GetMapping("/unauthorized")
    public JsonData unauthorized(){
        return JsonData.success("没有权限");
    }
}

注意访问路径要和shiroConfig里配置的一样
在这里插入图片描述
添加一个拦截器:
在这里插入图片描述
可以看到我给这访问路径设置有两个角色可访问,设想中应该是只要拥有其中一个角色就可以访问。写个接口测试一下:

/**
 * @author 黄豪琦
 * 日期:2019-07-11 14:48
 * 说明:
 */
@RequestMapping("/manage")
@RestController
public class ManageController {
    
    @GetMapping("/roleTest")
    public JsonData roleTest(){
        return JsonData.success("访问成功");
    }
}

数据库中显示刘备和赵云分别拥有root、admin角色:
在这里插入图片描述
启动项目,使用刘备登录:
在这里插入图片描述
访问显示没有权限:
在这里插入图片描述
之所以会这样是因为shiro自带的拦截器roles 规定的,如果配置了多个角色,那么就需要全部拥有这些角色;全局搜索DefaultFilter
在这里插入图片描述
按ctrl点进去查看
在这里插入图片描述
可以看到调用的是hasAllRoles,那么只要有一个角色没有就不会通过。

自定一个Role拦截器

在了解了原生role的原理后完全可以仿照它自己写一个拦截器来实现需求。
新建RoleOneAuthorizationFilter(名字越长越nb,按照shiro的风格来),继承AuthorizationFilter,然后要求实现一个方法,这个方法在用到这个拦截器时会执行,返回false表示自己已处理,返回true表示继续往下执行。 然后直接把RolesAuthorizationFilter中的复制过来改一改就可以了。

/**
 * @author 黄豪琦
 * 日期:2019-07-11 15:16
 * 说明:自定义role拦截器
 */
public class RoleOneAuthorizationFilter extends AuthorizationFilter {

    public RoleOneAuthorizationFilter(){}

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        Subject subject = this.getSubject(request, response);
        //获取当前路径所需要的角色
        String[] rolesArray = (String[])mappedValue;
        //如果有配置,那说明对角色有要求
        if (rolesArray != null && rolesArray.length != 0) {
            Set<String> roles = CollectionUtils.asSet(rolesArray);
            boolean flat = false;
            for(String item : roles){
                //判断是否有这个角色
                if(subject.hasRole(item)){
                    flat = true;
                }
            }
            return flat;
        } else {
            return true;
        }
    }
}

将自定义的filter添加到拦截器工厂中去:
在这里插入图片描述
然后在过滤链中修改
在这里插入图片描述
重启项目再访问:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值