欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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 拦截器和自定义注解的资料请关注其它相关文章!