繁体   English   中英

如何在 Quarkus 应用程序中检索 SecurityContext?

[英]How to retrieve SecurityContext in a Quarkus application?

我有一个 Quarkus 应用程序,我在其中实现了ContainerRequestFilter接口以从传入请求中保存 header:

@PreMatching
public class SecurityFilter implements ContainerRequestFilter {
   private static final String HEADER_EMAIL = "HD-Email";

   @Override
   public void filter(ContainerRequestContext requestContext) throws IOException {
       String email = requestContext.getHeaders().getFirst(HEADER_EMAIL);

       if (email == null) {
           throw new AuthenticationFailedException("Email header is required");
       }

       requestContext.setSecurityContext(new SecurityContext() {
           @Override
           public Principal getUserPrincipal() {
               return () -> email;
           }

           @Override
           public boolean isUserInRole(String role) {
               return false;
           }

           @Override
           public boolean isSecure() {
               return false;
           }

           @Override
           public String getAuthenticationScheme() {
               return null;
           }
       });
   }
}

在使用ApplicationScoped注释的 class 中,我注入了如下上下文:

@ApplicationScoped
public class ProjectService {
    @Context
    SecurityContext context;
    ...
}

问题是context属性实际上从未注入,因为它始终是null

我究竟做错了什么? 我应该怎么做才能在整个应用程序代码中检索SecurityContext

我喜欢将这个问题抽象化,以便业务逻辑不依赖于特定于 JAX-RS 的构造。 因此,我创建了一个 class 来描述我的用户,比如User和另一个接口AuthenticationContext ,它包含当前用户和我需要的任何其他身份验证相关信息,例如:

public interface AuthenticationContext {
    User getCurrentUser();
}

我创建了这个 class 的RequestScoped实现,它也有相关的设置器:

@RequestScoped
public class AuthenticationContextImpl implements AuthenticationContext {
    private User user;

    @Override
    public User getCurrentUser() {
        return user;
    }

    public void setCurrentUser(User user) {
        this.user = user;
    }
}

现在,我将这个 bean 和 JAX-RS SecurityContext注入到一个过滤器中,它知道如何创建User并将其设置到我的应用程序特定的AuthenticationContext中:

@PreMatching
public class SecurityFilter implements ContainerRequestFilter {

    @Inject AuthenticationContextImpl authCtx; // Injecting the implementation,
                                               // not the interface!!!

    @Context SecurityContext securityCtx;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        User user = ...// translate the securityCtx into a User
        authCtx.setCurrentUser(user);
    }
}

然后,任何需要用户数据的业务 bean 都会注入环境中立的、特定于应用程序的AuthenticationContext

@Context只能在 JAX-RS 类中使用 - 即用@Path注释的类。

在您的情况下, ProjectService是 CDI bean,而不是 JAX-RS class。

执行所需操作的规范方法是将SecurityContext注入 JAX-RS 资源,然后将其作为方法参数传递给ProjectService

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM