我使用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
为空。
答案 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;
但我没有尝试。但是通过限定符注入现在正在工作(注入安全上下文)。