Введенный контекст 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;
Но я не пытался. Но инъекция через квалификатор сейчас работает (контекст безопасности вводится).