SpringBoot+拦截器+自定义注解实现权限控制

本文介绍了一种基于自定义注解的权限控制方案,包括注解定义、使用及权限验证流程。通过创建自定义注解、应用到控制器方法,并借助自定义拦截器完成权限检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、创建自定义注解

package com.shenlan.common.annotation;

import java.lang.annotation.*;

/**
 * @author : xukun
 * @date : 2020/9/17
 */

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface RequestAuthority {

    String[] value();
    //所有的权限都满足,默认为false,表示满足一个就可以
    boolean andAuthority() default false;
}

二、在控制器的方法上使用该注解

@PostMapping("/search")
@ResponseBody
@ApiOperation(value = "查询或检索图层列表")
//这些权限只需要满足一个就可以
@RequestAuthority(value = {AuthorityConstant.INDEX_LAYER_QUERY, AuthorityConstant.LAYER_LIST,
        AuthorityConstant.LAYER_QUERY, AuthorityConstant.RELATIONWITHLAYER_QUERY,
        AuthorityConstant.RELATION_QUERY, AuthorityConstant.RELATION_LAYER_QUERY,
        AuthorityConstant.LAYER_APPROVAL_LAYER_LIST, AuthorityConstant.LAYER_APPROVAL_LAYER_QUERY
})
public ResponseData search(@RequestParam(defaultValue = "1") int pageNo,
                           @RequestParam(defaultValue = "10") int pageSize, @RequestBody LayerSearchPO params) {
    PageHelper.startPage(pageNo, pageSize);
    return ResponseDataUtil.buildSuccess(new PageInfo<>(service.list(params)));
}

三、创建自定义拦截器,继承HandlerInterceptorAdapter,重写preHandle方法,那么所有的请求在进入控制器前都会被该方法拦截。我们在这个方法里面进行权限的认证。

/**
 * @author : xukun
 * @date : 2020/9/21
 */
public class SecurityInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    UserInfoService userInfoService;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!isAuthority(handler)) {
            throw new BDException("没有操作权限");
        }
        return true;
    }

    /**
     * 判断此次请求是否有权限
     *
     * @param handler
     * @return 有权限返回true
     */
    private boolean isAuthority(Object handler) {
        boolean flag = true;
        if (handler instanceof HandlerMethod) {
            //获得请求的方法
            Method method = ((HandlerMethod) handler).getMethod();
            //获得该方法上面的注解,如果没有注解,直接返回true,通过
            RequestAuthority annotation = method.getAnnotation(RequestAuthority.class);
            if (annotation != null) {
                //得到当前登录人的权限,判断请求的权限是否包含在内
                QueryUserAuthRequest request = new QueryUserAuthRequest();
                request.setUserId(UserUtils.getLogInfo().getId());
                request.setAppCode(Long.valueOf(SysConstant.appCode));
                List<String> authorlist;
                try {
                    authorlist = userInfoService.getAuthorByUserId(request).getData();

                } catch (RestTemplateException e) {
                    throw new BDException(e.getMessage());
                }
                //获得注解的值(权限)
                String[] values = annotation.value();
                //是否所有的权限都满足才可以
                boolean andAuthority = annotation.andAuthority();
                if (andAuthority) {//该请求所有的权限都满足才可以
                    flag = containsCheck(Arrays.asList(values), authorlist);
                } else {
                    flag = haveCheck(Arrays.asList(values), authorlist);
                }
            }
        }
        return flag;
    }

    /**
     * 判断权限列表中是否包含给定权限
     *
     * @param targets 给定权限
     * @param sources 权限列表
     * @return 全部包含返回true
     */
    private boolean containsCheck(List<String> targets, List<String> sources) {
        if (targets == null || sources == null || targets.size() > sources.size()) {
            return false;
        }
        for (String target : targets) {
            if (!sources.contains(target)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断权限列表中是否有给定权限
     *
     * @param targets 给定权限
     * @param sources 权限列表
     * @return 包含一个返回true
     */
    private boolean haveCheck(List<String> targets, List<String> sources) {
        if (targets == null || sources == null || targets.size() > sources.size()) {
            return false;
        }
        for (String target : targets) {
            if (sources.contains(target)) {
                return true;
            }
        }
        return false;
    } 
}

四、创建配置类,实现WebMvcConfigurer接口,重写addInterceptors方法,添加拦截器。

/**
 * @author xukun
 * @date 2020/7/28
 */
@Configuration
public class StaticConfig implements WebMvcConfigurer {
	/**
	 * 将自定义的拦截器交给Spring容器管理
	 */
    @Bean
    public SecurityInterceptor getSecurityInterceptor() {
        return new SecurityInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	//添加自定义的拦截器
        InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());
        //拦截所有请求
        addInterceptor.addPathPatterns("/**");
    }
}

五、重启项目,进行测试

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值