You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:07:32