Введенный контекст SecurityContext имеет значение null

Я создал приложение Javae EE, используя JAX-RS 2.0 и JPA. Я создал специального провайдера для своей сущности User (используя Qualifiers), чтобы предоставить текущего пользователя (вошедшего в систему) как сущность из пользовательской базы данных приложений. Чтобы получить текущего пользователя я использую

@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 для нуля, и я вижу свое исключение, как только я пытаюсь найти ресурс, который внедряет @CurrentUser,

Так как это исправить? Почему SecurityContext ноль.

2 ответа

Как указано в моем комментарии

SecurityContext является компонентом JAX-RS и может быть введен только в другой компонент JAX-RS. Все, что у вас есть, это боб CDI. Вы можете попробовать сделать его EJB и внедрить SessionContext, См. Защита корпоративного компонента программно

Не проверял, но, кажется, работает на OP. Это решение для стека EE.

Еще один JAX-RS (специфичный для Resteasy) способ сделать инъекцию - с помощью ResteasyProviderFactory (найдено с помощью этого ответа). Вы можете использовать это в ContainerRequestFilter, который имеет доступ к SecurityContext, Мы можем использовать служебный класс RESTeasy для User в контекст. Это позволяет для инъекций с @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

Я нашел другой способ получить класс, распознаваемый Jax-R: реализация ContextResolver и аннотирование класса с помощью провайдера.

Для реализации интерфейса я добавил:

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

Я не уверен, но, вероятно, с этим я могу сделать

@Context private User currentUser;

Но я не пытался. Но инъекция через квалификатор сейчас работает (контекст безопасности вводится).

Другие вопросы по тегам