Quarkus 3中TrustedAuthenticationRequest多次调用是否为预期行为?
我用Quarkus 3搭配Primefaces扩展构建JSF应用,已经配置了表单认证。查看源码发现FormAuthenticationMechanism会返回UsernamePasswordAuthenticationRequest和TrustedAuthenticationRequest两种凭证类型,我已经实现了这两种类型的认证逻辑。但对TrustedAuthenticationRequest的工作机制有疑问:请求JSF页面时,对应的身份提供器会被多次调用,似乎每个静态资源(比如css、js)都会触发一次,单个页面的调用次数甚至超过10次,而且每次调用都会重新设置主体和角色,这看起来非常冗余。想知道这是预期行为还是我的实现有问题?
我的TrustedAuthenticationRequest认证实现代码如下:
@Override public Uni<SecurityIdentity> authenticate(TrustedAuthenticationRequest request, AuthenticationRequestContext authenticationRequestContext) { if (Objects.nonNull(request.getPrincipal())) { return Uni.createFrom().item(QuarkusSecurityIdentity.builder() .setPrincipal(new QuarkusPrincipal(request.getPrincipal())) .addRoles(Set.of("create", "read", "update", "delete")) .build()); } throw new AuthenticationFailedException("password invalid or user not found"); }
这属于预期行为,但你的实现可以优化来避免冗余操作。
为什么会多次触发?
Quarkus的表单认证机制中,TrustedAuthenticationRequest是用来处理已认证用户的后续请求的——当用户通过表单登录后,后续的每个请求(包括页面内的静态资源请求)都会携带认证凭据(比如会话cookie),Quarkus会通过这个请求类型来验证用户身份并构建SecurityIdentity。
JSF页面通常会加载大量静态资源(Primefaces的css、js、图标等),每个资源请求都是独立的HTTP请求,所以每个请求都会触发一次认证逻辑调用,这就导致了你看到的多次调用情况。
如何优化你的实现?
目前你的代码每次调用都会重新创建QuarkusPrincipal和角色集合,确实存在冗余。可以通过以下方式优化:
- 缓存已构建的
SecurityIdentity:如果请求中的Principal是同一个,可以缓存对应的SecurityIdentity实例,避免重复构建。 - 利用Quarkus的会话缓存:Quarkus默认会在会话中存储已认证的
SecurityIdentity,你可以检查AuthenticationRequestContext中是否已有认证信息,或者配置Quarkus的安全会话缓存来减少重复构建。
另外,注意你的代码中抛出的异常信息——当request.getPrincipal()为null时抛出的AuthenticationFailedException信息是"password invalid or user not found",这和TrustedAuthenticationRequest的场景不匹配,应该改为更贴合的提示(比如"Trusted authentication principal missing"),避免混淆问题。
内容的提问来源于stack exchange,提问作者Jeff Rogers

