注入的上下文SecurityContext为null

时间:2015-06-02 14:52:35

标签: java dependency-injection jax-rs resteasy security-context

我使用JAX-RS 2.0和JPA创建了一个Javae EE应用程序。我创建了一个特殊的User实体提供程序(使用限定符),以便从应用程序用户数据库中提供当前用户(已登录)作为实体。 要获得当前用户,请使用

@Context
private SecurityContext secContext;

问题是这是空的。安全性设置正常(Wildfly 8.2) - 应用程序要求身份验证(基本),但SecurityContext为空。这是代码:

@RequestScoped
public class CurrentUserProducer implements Serializable {

    /**
     * Default
     */
    private static final long serialVersionUID = 1L;

    @Context
    private SecurityContext secContext;

    /**
     * Tries to find logged in user in user db (by name) and returns it. If not
     * found a new user with role {@link UserRole#USER} is created.
     * 
     * @return found user a new user with role user
     */
    @Produces
    @CurrentUser
    public User getCurrentUser() {
        if (secContext == null) {
            throw new IllegalStateException("Can't inject security context - security context is null.");
        //... code to retrieve or create new user
        return user;
    }

}

如您所见,我检查secContext是否为null,一旦我尝试访问注入@CurrentUser的资源,我就会看到我的异常。

那么如何解决这个问题呢?为什么SecurityContext为空。

2 个答案:

答案 0 :(得分:1)

如我的评论中所述

  

SecurityContext是一个JAX-RS组件,只能注入其他JAX-RS组件。你所拥有的只是一个CDI bean。您可以尝试将其设为EJB并注入SessionContext。请参阅保护Enterprise Bean Programmatically

尚未测试但似乎适用于OP。这是一个EE堆栈解决方案。

允许注射的另一种JAX-RS(Resteasy特定)方法是在ResteasyProviderFactory的帮助下(在this answer的帮助下找到)。您可以在ContainerRequestFilter中使用此功能,该SecurityContext可以访问User。我们可以使用RESTeasy实用程序类将@Context推送到上下文中。这允许使用@Provider public class UserContextFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext context) throws IOException { SecurityContext securityContext = context.getSecurityContext(); String username = securityContext.getUserPrincipal().getName(); ResteasyProviderFactory.pushContext(User.class, new User(username)); } } 注释进行注入。不知道如何/如果它可以使用自定义注释。这是一个例子

ContainerRequestFilter

注意:这是一个JAX-RS 2.0解决方案(即RESTeasy 3.x.x)。在2.0之前,没有COUNT

答案 1 :(得分:0)

我找到了另一种让Jax-Rs识别出类的方法:实现ContextResolver并用提供者注释类。

实现我添加的界面:

@Override
public User getContext(Class<?> type) {
    if (type.equals(User.class)){
        return getCurrentUser();
    }
    return null;
}

我不确定,但我可以做到这一点

@Context 私人用户currentUser;

但我没有尝试。但是通过限定符注入现在正在工作(注入安全上下文)。