2

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

@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;
    }

}

如您所见,我检查secContextnull 并且一旦我尝试访问注入的资源,我就会看到我的异常@CurrentUser

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

4

2 回答 2

2

正如我的评论所述

SecurityContext是一个 JAX-RS 组件,只能注入到其他 JAX-RS 组件中。你所拥有的只是一个 CDI bean。您可以尝试使其成为 EJB 并注入SessionContext. 请参阅以编程方式保护Enterprise Bean

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

允许注入的另一种 JAX-RS(Resteasy 特定)方法是借助(在此答案ResteasyProviderFactory的帮助下找到)。您可以在 a 中使用它,它可以访问. 我们可以使用 RESTeasy 实用程序类将其推送到上下文中。这允许使用注解进行注入。不确定如何/是否可以使用自定义注释。这是一个例子ContainerRequestFilterSecurityContextUser@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));
    }  
}

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

于 2015-06-03T08:38:29.110 回答
0

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

为了实现我添加的接口:

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

我不确定,但可能我可以做到

@Context 私有用户当前用户;

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

于 2015-06-03T07:23:52.933 回答