Quarkus 3.6.5+无法注入SecurityContext问题求助
Quarkus 3.6.5+中Hibernate Envers无法注入SecurityContext的问题
我正尝试解决jakarta.ws.rs.core.SecurityContext的注入问题。使用Hibernate Envers对名为Movie的实体进行审计,为获取SecurityContext采用了社区方案,但该方案在Quarkus 3.6.5+版本中无法工作,仅在Quarkus 3.6.4中可正常运行。CustomRevisionListener类中注入的SecurityContext始终返回null,导致审计日志中的用户邮箱始终为"anonymous"。
相关代码
CustomRevisionListener类
package org.acme; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import org.hibernate.envers.RevisionListener; import org.jboss.logging.Logger; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.acme.Log; import io.quarkus.arc.Unremovable; import io.quarkus.security.identity.SecurityIdentity; import io.vertx.core.http.HttpServerRequest; import io.vertx.mutiny.ext.web.RoutingContext; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.SecurityContext; @ApplicationScoped @Unremovable public class CustomRevisionListener implements RevisionListener { private final Logger logger = Logger.getLogger(CustomRevisionListener.class); @Inject SecurityContext securityContext; // @Inject // UserRepository userRepository; @Override public void newRevision(Object revisionEntity) { Log log = (Log) revisionEntity; log.setCreationDate(LocalDateTime.ofInstant(Instant.ofEpochMilli(log.getTimestamp()), ZoneId.systemDefault())); String usermail = "anonymous"; if(securityContext != null && securityContext.getUserPrincipal() != null) { usermail = securityContext.getUserPrincipal().getName(); } log.setUser(usermail); HttpServerRequest request = ResteasyProviderFactory.getInstance().getContextData(HttpServerRequest.class); log.setIp(request.remoteAddress().hostAddress()); } }
CustomSecurityContext限定符注解
package org.acme; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import jakarta.inject.Qualifier; @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) public @interface CustomSecurityContext { }
SecurityRequestFilter过滤器类
package org.acme; import java.io.IOException; import jakarta.enterprise.context.RequestScoped; import jakarta.ws.rs.Produces; import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.container.ContainerResponseContext; import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.ext.Provider; @Provider public class SecurityRequestFilter implements ContainerRequestFilter, ContainerResponseFilter { private static final ThreadLocal<SecurityContext> THREAD_LOCAL = new ThreadLocal<>(); @RequestScoped @Produces @CustomSecurityContext public SecurityContext getSecurityContext() { return THREAD_LOCAL.get(); } @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { THREAD_LOCAL.remove(); } @Override public void filter(ContainerRequestContext requestContext) throws IOException { THREAD_LOCAL.set(requestContext.getSecurityContext()); } }
环境配置
使用Keycloak OIDC连接、RESTEasy Classic、MySQL JDBC连接,配置如下:
# OIDC Configuration quarkus.oidc.auth-server-url=http://localhost:8080/realms/quarkus quarkus.oidc.client-id=ensitec quarkus.oidc.credentials.secret=vZOXyggQW2N2bxjy4pdWSNJetL4pm1C9 quarkus.oidc.tls.verification=none # CORS Configuration quarkus.http.cors=true quarkus.http.cors.origins=* quarkus.http.cors.methods=GET,DELETE,POST,PUT,OPTIONS quarkus.http.cors.access-control-allow-credentials=true quarkus.hibernate-envers.audit-table-prefix=_
疑问
这是Hibernate Envers的Bug吗?有没有其他获取SecurityContext的方法?
内容的提问来源于stack exchange,提问作者Nathan Ruba
相关产品推荐
相关产品推荐

