暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

springboot webflux 过滤器中识别自定义注解校验Token

java知路 2021-08-11
2616



在WebFilter中识别web接口上添加的自定义注解:

Controller的接口如下(@Token是自己建立的注解):

    @Token
@GetMapping("/test")
public Mono<String> test() {
return Mono.just("success");
}

WebFilter代码:

import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.MultiValueMap;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;


@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class TokenFilter implements WebFilter {

@Resource
private RequestMappingHandlerMapping requestMappingHandlerMapping;

private boolean flag;

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
// 获取Response、Request
ServerHttpResponse res = exchange.getResponse();
ServerHttpRequest req = exchange.getRequest();

// 获取请求对应的HandlerMethod
Mono<HandlerMethod> handlerMethodMono = requestMappingHandlerMapping
.getHandler(exchange).cast(HandlerMethod.class);

handlerMethodMono.subscribe(handlerMethod -> {
// 判断Method是否含有对应注解
flag = handlerMethod.hasMethodAnnotation(Token.class);
if (!flag) return;

// TODO: 校验Token
MultiValueMap<String, String> params = req.getQueryParams();
HttpHeaders headers = req.getHeaders();


}).dispose();

// 过滤器正常放行
if (!flag) return chain.filter(exchange);

// TODO: 校验不通过,返回错误信息
res.setStatusCode(HttpStatus.NON_AUTHORITATIVE_INFORMATION);
byte[] bytes = "NON_AUTHORITATIVE_INFORMATION".getBytes();
return res.writeWith(Mono.just(res.bufferFactory().wrap(bytes)));
}

}


一些可能不用在意的点:
1、Token.class改成自己对应的注解

flag = handlerMethod.hasMethodAnnotation(Token.class);

2、设置状态码不是必须的,但这是个枚举型,里面可能没有一些你想要的奇怪值

res.setStatusCode(HttpStatus.NON_AUTHORITATIVE_INFORMATION);

3、自定义的返回内容要转成byte数组

byte[] bytes = "NON_AUTHORITATIVE_INFORMATION".getBytes();
return res.writeWith(Mono.just(res.bufferFactory().wrap(bytes)));

4、你需要的请求参数可以从这儿取

MultiValueMap<String, String> params = req.getQueryParams();
HttpHeaders headers = req.getHeaders();

5、Debug了几遍,RequestMappingHandlerMapping的beanName是requestMappingHandlerMapping,他记录了所有接口地址和对应方法

@Resource
private RequestMappingHandlerMapping requestMappingHandlerMapping;

6、springboot版本

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/>
</parent>


文章转载自java知路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论