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

一、创建自定义注解

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("/**");
    }
}

五、重启项目,进行测试

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
# spring-boot-auth-starter 基于`spring boot web`的权限拦截验证 ## 重要声明 * 本分支由`1.0.7`为第一个版本,此版本默认提供`guava`存储令牌的功能 * 根据`guava`的缓存特性,提供了`2`种缓存方案(`LoadingCache、Cache`) * 如果需要使用`redis`存储方案,参考: [四、自定义缓存方案](#jump) ;或请直接使用`1.0.5`版本(有一些遗留`bug`) ## 一、使用前需要的准备 * maven中央仓库地址 [其他方式集成](https://search.maven.org/artifact/com.github.liuchengts/spring-boot-auth-starter) ``` <dependency> <groupId>com.github.liuchengts</groupId> <artifactId>spring-boot-auth-starter</artifactId> <version>1.0.7.4</version> </dependency> ``` * 声明一个接口来抽象具体的权限,可以继承 `com.boot.auth.starter.common.DefaultRolesConstant` ```java /** * 当前服务自定义的权限权限为平级验证,不是包含关系 * 即 某资源 满足 user1或者user2即可 * <p> * <p> * extends DefaultRolesConstant 这个继承不是必须的 */ //todo 在这里自己定义权限角色 public interface RolesConstant extends DefaultRolesConstant { /** * user1 **/ String USER_1 = "USER1"; /** * user2 **/ String USER_2 = "USER2"; } ``` * 在项目的`application.yml`文件中,根据实际情况配置 `com.boot.auth.starter.common.AuthProperties` 值 ``` info: auth: tokenPrefix: test # 令牌存储前缀(必须) overdueTime: 9999999999 # 令牌过期时间,单位秒(必须) domain: localhost # 授权域名(必须) exclude: true # 账户令牌排他性,true 表示一个账号只会保留最后一次生成的令牌;false 表示一个账号可以对应多个令牌(非必须,默认 false) cacheInitialCapacity: 100 # guava 缓存的初始大小(非必须,默认 由guava 自行设置) cacheMaximumSize: 2000 # guava 设置缓存最大容量,超过之后就会按照LRU最近虽少使用算法来移除缓存项(非必须,默认 由guava 自行设置) cacheStats: true # guava 缓存统计(非必须,默认 false) loadingCache: false # guava 启用 loadingCache 作为缓存器(非必须,默认 false) ``` ## 二、使用示例 `使用示例demo` [spring-boot-auth-starter-example](https://github.com/liuchengts/spring-boot-auth-starter-example) * `@Auth` 权限注解(默认权限在 ```com.boot.auth.starter.common.DefaultRolesConstant```) * `@NoAuthGetSession` 不强制校验权限(默认不强制校验) * `@IgnoreLogin ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
Spring Boot实现拦截器的过程可以参考中提供的详细示例代码解析。在Spring Boot中,可以通过创建一个自定义的拦截器类来实现拦截功能。拦截器类需要实现Spring框架中的HandlerInterceptor接口,并重写其中的方法。 首先,需要创建一个拦截器类,该类需要实现HandlerInterceptor接口,并重写其中的preHandle、postHandle和afterCompletion方法。preHandle方法在请求处理之前执行,可以用于进行权限验证、日志记录等操作;postHandle方法在请求处理之后执行,可以对响应结果进行处理;afterCompletion方法在视图渲染之后执行,可以进行一些资源的清理操作。 接下来,需要在Spring Boot应用程序的配置类(通常是带有@SpringBootApplication注解的类)中注册拦截器。可以通过重写WebMvcConfigurer接口中的addInterceptors方法来实现。在该方法中,可以使用addInterceptor方法将自定义的拦截器类添加到拦截器链中,指定需要拦截的路径或排除的路径。 通过以上步骤,就可以实现拦截器Spring Boot应用中的使用了。拦截器会在请求到达控制器方法之前进行拦截,并执行拦截器类中定义的相关逻辑。 需要注意的是,拦截器Spring Boot中是针对Spring MVC的访问进行增强的,与Servlet技术中的过滤器(Filter)有所区别。拦截器通过动态拦截方法调用的机制来实现,而过滤器对所有访问进行增强。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值