如何解决如何修改 Micronaut Http 过滤器的顺序,使其在 Micronaut Security
@Target(value = { ElementType.METHOD,ElementType.TYPE,ElementType.ANNOTATION_TYPE })
@Retention(value=RetentionPolicy.RUNTIME)
public @interface checkForBankId {
boolean ignore() default false;
}
public class BankIdSecurityService {
/*
* This is declarative client to call the
* InternalAPIs to get all details about the user;
*/
@Inject
UserRepositoryClient client;
static final boolean AUTHORIZED = true;
static final boolean UnAUTHENTICATED = false;
Flowable<Boolean> checkAuthentication(HttpRequest<?> request) {
if (routeMatch instanceof MethodBasedRouteMatch) {
MethodBasedRouteMatch<?,?> methodBasedRouteMatch =
(MethodBasedRouteMatch<?,?>) routeMatch;
if (methodBasedRouteMatch.hasAnnotation(checkForBankId.class)) {
String userName = getUserName(request).get();
if(!request.getParameter().contains("bankId")) {
return Flowable.just(UNAUTHORIZED);
}
return this.client.getUser(userName).map(userDetails -> {
String bankId = request.getParameter().get("bankId");
BankAccount[] bankAccounts = userDetails.getPayload().getBankAccounts();
boolean bankIdFound = false;
for(BankAcconut bankAccout: bankAccounts) {
if(bankAccount.getId().equals(bankId)) {
bankIdFound = true;
break;
}
}
return bankIdFound ? AUTHENTICATED : UNAUTHORIZED;
});
}
}
return Flowable.just(AUTHENTICATED);
}
Optional<String> getUserName(HttpRequest<?> request) {
// get jwt from request header
then parse the jwt and extract
the username from it and return;
}
}
然后我有每个请求执行一次的过滤器
@Filter(Filter.MATCH_ALL_PATTERN)
@AllArgsConstructor
@Slf4j
public class BankIdSecurityFilter extends OncePerRequestHttpServerFilter {
private final BankIdSecurityService bankIdSecurityService;
@Override
protected Publisher<MutableHttpResponse<?>> doFilterOnce(
HttpRequest<?> request,ServerFilterChain chain
) {
log.info("request route: {}",request);
return this.bankIdSecurityService
.checkAuthentication(request).switchMap(authResult -> {
log.info("authentication result: {}",authResult);
return authResult ? // if authResult is true then proceed as usual
chain.proceed(request) :
Publishers.just(HttpResponse.status(HttpStatus.BAD_REQUEST)
.body("This bankId doesn't belond to this user.")
); // return bad request
});
}
@Override
public int getorder() {
return ServerFilterPhase.Security.after();
}
}
在控制器内部,我们将 @CheckForBankId 应用到我们想要过滤请求的地方
@CheckForBankId
@GET("get-bank-account?{bankId}")
Single<BankAccount> getBankAccount(String bankId) {
return someService.getBankAccount(bankId);
}
过滤器工作正常。缺少的是它在 microanut 之前被执行 因此,标头中的令牌未经身份验证,并且在某些情况下它可以 导致一些问题,例如如果过期的令牌传递给标头并且我的解析器将解析 令牌并将从中返回用户,但这没有意义,因为令牌已经无效。它应该在进入过滤器之前就已经被拒绝了......所以,像这个过滤器一样 在 micronaut 安全之后执行。我尝试覆盖 getorder 方法,但没有用 :(
解决方法
您没有指定您使用的是哪个 Micronaut 版本,但答案是该行为是一个错误。它应该在 Micronaut 2.5.4 中按预期工作
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。