【发布时间】:2018-11-05 15:02:18
【问题描述】:
我正在尝试实现一个 WebFilter 来检查 JWT,如果检查失败或结果无效则抛出异常。我有一个处理这些异常的@ControllerAdvice 类。但它不起作用。
这是WebFilter 类:
@Component
public class OktaAccessTokenFilter implements WebFilter {
private JwtVerifier jwtVerifier;
@Autowired
public OktaAccessTokenFilter(JwtVerifier jwtVerifier) {
this.jwtVerifier = jwtVerifier;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return Optional.ofNullable(exchange.getRequest().getHeaders().get("Authorization"))
.flatMap(list -> list.stream().findFirst())
.filter(authHeader -> !authHeader.isEmpty() && authHeader.startsWith("Bearer "))
.map(authHeader -> authHeader.replaceFirst("^Bearer", ""))
.map(jwtString -> {
try {
jwtVerifier.decodeAccessToken(jwtString);
} catch (JoseException e) {
throw new DecodeAccessTokenException();
}
return chain.filter(exchange);
}).orElseThrow(() -> new AuthorizationException());
}
}
以及异常处理程序:
@ControllerAdvice
public class SecurityExceptionHandler {
@ExceptionHandler(AuthorizationException.class)
public ResponseEntity authorizationExceptionHandler(AuthorizationException ex) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
@ExceptionHandler(DecodeAccessTokenException.class)
public ResponseEntity decodeAccessTokenExceptionHandler(DecodeAccessTokenException ex) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}
我认为,@ControllerAdvice 类无法处理WebFilter 抛出的异常。因为,如果我将异常移动到控制器,它就可以工作。
我已经更改了代码(暂时):
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Optional<String> authJwt = Optional.ofNullable(exchange.getRequest().getHeaders().get("Authorization"))
.flatMap(list -> list.stream().findFirst())
.filter(authHeader -> !authHeader.isEmpty() && authHeader.startsWith("Bearer "))
.map(authHeader -> authHeader.replaceFirst("^Bearer", ""));
if (authJwt.isPresent()) {
String jwtString = authJwt.get();
try {
jwtVerifier.decodeAccessToken(jwtString);
} catch (JoseException e) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().writeWith(Mono.empty());
}
} else {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().writeWith(Mono.empty());
}
return chain.filter(exchange);
}
你怎么看这个问题?你知道另一种实现方式吗?
【问题讨论】:
标签: java spring-webflux