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



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

@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注释的类中,我注入了如下上下文:

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

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

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

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

public interface AuthenticationContext {
User getCurrentUser();
}

我创建了这个类的RequestScoped实现,它也有相关的setter:

@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-RSSecurityContext注入到一个过滤器中,该过滤器知道如何创建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是一个CDIBean,而不是JAX-RS类。

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

相关内容

  • 没有找到相关文章

最新更新