SpringBoot 拦截器和自定义注解判断请求是否合法
应用场景举例:
当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释
自定义注解
/**
* 对比请求的用户身份是否符合
* @author liuyalong
* @date 2020/9/25 16:03
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CompareUser {
/**
* The name of the request parameter to bind .
*/
@AliasFor("name") String value() default "";
@AliasFor("value") String name() default "";
}
给controller的字段添加注解
@ApiOperation(value = "删除用户", notes = "根据手机号来删除用户")
@PostMapping(value = "/delete_phone")
public BaseCommonResult<Integer> deletePhone(@CompareUser(value = "phone") String phone) {
int i = userService.deleteByPhone(phone);
return BaseCommonResult.success(i);
}
参数解析器
记得继承后加@Component,这里是Base...所以不用
/**
* @author liuyalong
* @date 2020/9/25 15:56
*/
public class BaseCurrentUserInterceptor implements HandlerMethodArgumentResolver {
/**
* 用于判定是否需要处理该参数注解,返回true为需要,
* 并会去调用下面的方法resolveArgument。
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
//只处理CurrentUser注解修饰的参数
return parameter.hasParameterAnnotation(CompareUser.class);
}
/**
* 对比用户信息
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CompareUser parameterAnnotation = parameter.getParameterAnnotation(CompareUser.class);
Class<?> parameterType = parameter.getParameterType();
if (parameterAnnotation == null) {
throw new IllegalArgumentException("Unknown parameter type [" + parameterType.getName() + "]");
}
/*
* 获取要验证的字段名
*/
//检查是否给字段取了别名
String paramName = "".equalsIgnoreCase(parameterAnnotation.name()) ? parameterAnnotation.value() : parameterAnnotation.name();
if ("".equalsIgnoreCase(parameterAnnotation.name())) {
//从参数中获取定义的字段名
paramName = parameter.getParameter().getName();
}
//获取请求字段的值
String paramValue = String.valueOf(webRequest.getParameter(paramName));
//从请求头中获取已经登录的用户
String userName = webRequest.getHeader(AuthConstant.USER_TOKEN_HEADER);
//对于root用户,可以操作一切,所以直接返回
if (!AuthConstant.ROOT_USER.equals(userName)) {
//判断身份是否一致,不一致就抛出异常,让RestControllerAdvice处理
if (userName == null || !userName.equals(paramValue)) {
throw new NotSameAuthorException();
}
}
//将参数原封不动返回出去,需要还原回需要的类型
WebDataBinder binder = binderFactory.createBinder(webRequest, parameterType, paramName);
return binder.convertIfNecessary(paramValue, parameterType, parameter);
}
}
配置WebMvcConfigurer
注意这里提供了两种方式加载,因为
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private HandlerInterceptor handlerInterceptor;
@Autowired
private HandlerMethodArgumentResolver currentUserInterceptor;
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(handlerInterceptor).addPathPatterns("/**");
}
//参数解析器,自定义的优先级最低,所以会失效,
// 解决方案是下面的 @PostConstruct ,把优先级调最高
// 但是这样@PathParam @RequestParam就失效了,@CompareUser(value="xxx")可以完全替换@RequestParam功能
// @Override
// public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
// resolvers.add(currentUserInterceptor);
//
// }
/**
*参数解析器优先级调最高
*/
@PostConstruct
public void init() {
// 获取当前 RequestMappingHandlerAdapter 所有的 Resolver 对象
List<HandlerMethodArgumentResolver> resolvers = requestMappingHandlerAdapter.getArgumentResolvers();
List<HandlerMethodArgumentResolver> newResolvers = new ArrayList<>(resolvers.size() + 1);
// 添加自定义参数解析器到集合首位
newResolvers.add(currentUserInterceptor);
// 添加 已注册的 Resolver 对象集合
newResolvers.addAll(resolvers);
// 重新设置 Resolver 对象集合
requestMappingHandlerAdapter.setArgumentResolvers(newResolvers);
}
}
效果
只有特定身份人员才可以删除操作
SpringBoot 拦截器和自定义注解判断请求是否合法的更多相关文章
- struts2拦截器加自定义注解实现权限控制
https://blog.csdn.net/paul342/article/details/51436565 今天结合Java的Annotation和Struts2进行注解拦截器权限控制. 功能需求: ...
- 拦截器和自定义注解@interface
1 .拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在Handler执行之前或之后加入某些操作,其实就是AOP的一种实现策略. 拦截用户的请求并进行相应的处理,比如:判断用 ...
- [Java]利用拦截器和自定义注解做登录以及权限验证
1.自定义注解 需要验证登录的注解 package com.etaofinance.wap.common; import java.lang.annotation.Documented; import ...
- Spring MVC基础知识整理➣拦截器和自定义注解
概述 Spring MVC中通过注解来对方法或者类进行动态的说明或者标注,类似于配置标识文件的属性信息.当标注的类或者方式被使用时候,通过提取注解信息来达到对类的动态处理.在 MVC中,我们常用的注解 ...
- SpringMVC拦截器+Spring自定义注解实现权限验证
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- springboot + 拦截器 + 注解 实现自定义权限验证
springboot + 拦截器 + 注解 实现自定义权限验证最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定义 ...
- 【SpringBoot】SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener
=================6.SpringBoot拦截器实战和 Servlet3.0自定义Filter.Listener ============ 1.深入SpringBoot2.x过滤器Fi ...
- SpringBoot 拦截器获取http请求参数
SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 目录 SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 获取http请求参数是一种刚需 定义拦截器获取请求 为 ...
- springboot拦截器总结
Springboot 拦截器总结 拦截器大体分为两类 : handlerInterceptor 和 methodInterceptor 而methodInterceptor 又有XML 配置方法 和A ...
随机推荐
- ssh2中的添,删,查,改。
1.spring封装的HibernateTemplate类的一些操作方法. 2.session提供的根据主键ID进行添.删.查.改的基本方法. 由session得到的hql语句 由session得到的 ...
- oracle的迁移工作
1.创建新数据库用户 1).创建用户和分配权限 sqlplus / as sysdba create user ENFRC_TEST_GZ_TMP identified by ENFRC_TEST_G ...
- tcp黏包问题与udp为什么不黏包
1.先说下subprocess模块的用法,为了举个黏包的例子 # 通过一个例子 来认识网络编程中的一个重要的概念 # 所有的客户端执行server端下发的指令,执行完毕后,客户端将执行结果给返回给服务 ...
- 常用命令合集『Postgres、Redis、Docker等等』每周更新,建议收藏备用
Command CMD POSTGRES 进入数据库命令行 psql -U 用户名 -d 数据库名 psql -U example -d exampledb 导出数据库 pg_dump -U 用户名 ...
- MySQL开发篇(未完待续)
一.索引 什么是索引? 索引是帮助Mysql提高获取数据的数据结构,换一句话讲就是"排好序的快速查找的数据结构". 1.索引的分类 MySQL主要的几种索引类型:1.普通索引.2. ...
- leetcode 33和 leetcode81
//感想: 1.对于这两题,我真的是做到吐,这篇博客本来是昨晚准备写的,但是对于这个第二题,我真的做到头痛,实在是太尼玛的吐血了,主要是我也是头铁,非要找到那个分界点. 2.其实之前在牛客网上做过非常 ...
- JavaSE 学习笔记05丨泛型、集合
Chapter. 10 泛型 10.1 泛型程序设计 泛型,指可以在类或方法中预支地使用未知的类型.泛型程序设计(Generic programming),意味着编写的代码可被很多不同类型的对象所重用 ...
- kafka入门之broker-水印和leader epoch
每个kafka副本对象都持有2个重要的属性:日志末端位移LEO,高水印HW Kafka对leader副本和follower副本的LEO更新机制是不同的,后面我们会详细讨论. Kafka对leader副 ...
- volatile使用
mq的故障延迟机制:
- [整理]qbxt集训10场考试 大 杂 烩 (后篇)
前篇 Contest 6 A 两个数,第 \(i\) 轮从较大数(如果相等就是第一个)里减去 \(i\) ,问操作不能进行时两数分别为多少. 首先把大数减到和小数差不多,然后我们会发现接下来两数会轮流 ...