SpringBoot 拦截器和自定义注解判断请求是否合法
程序员文章站
2022-03-04 22:37:52
应用场景举例:当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释自定义注解/** * 对比请求的用户身份是否符合 * @author liuy...
应用场景举例:
当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释
自定义注解
/** * 对比请求的用户身份是否符合 * @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 拦截器和自定义注解判断请求是否合法的详细内容,更多关于springboot 拦截器和自定义注解的资料请关注其它相关文章!