Как получить доступ к сеансу калитки из фильтра запросов Джерси-2?

В Джерси 1.x мы получили доступ к сеансу Wicket из атрибута сеанса (Джерси), как описано здесь https://stackoverflow.com/a/15767824/1399659.

При переходе на Jersey 2.x представляется правильным использовать фильтр ContainerRequestFilter, который также позволяет внедрять компоненты Spring. У нас это работает успешно, включая

<param-name>jersey.config.server.provider.packages</param-name>

в качестве параметра инициализации для ServletContainer и использования аннотации @Provider в реализации ContainerRequestFilter. Но этот контейнерный фильтр является одноэлементным, и внедрить в него HttpServletRequest невозможно (см. 2114)

В методе filter() у нас есть доступ к ContainerRequestContext, но не может получить оттуда доступ к HttpServletRequest.

Итак, есть ли способ:

  1. Включить инъекцию Spring bean в фильтр сервлета (также и с Джерси)?
  2. Доступ к запросу сервлета из ContainerRequestFilter?
  3. Доступ к сеансу калитки из объекта, поддерживающего Spring-bean, с возможностью фильтрации Джерси каким-то другим способом?

`

import java.io.IOException;

import javax.servlet.http.HttpSession;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.Provider;

import org.apache.wicket.injection.Injector;

@Provider
public class SecurityContextFilter implements ContainerRequestFilter {

//@Context
//HttpServletRequest webRequest;

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
    //HttpSession httpSession = webRequest.getSession();
    //MyWicketSession mySession = (MyWicketSession) httpSession.getAttribute("wicket:" + BaseConstants.WICKET_FILTER_NAME + ":session");
    //doAuthCheck(mySession, requestContext);
}
...
}

`

заранее спасибо


person Brad M    schedule 30.09.2013    source источник


Ответы (1)


Исправлено в Джерси 2.4:

import javax.annotation.Priority;
import javax.ws.rs.Priorities;

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthRequestFilter implements ContainerRequestFilter {
    @Context
    HttpServletRequest webRequest;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        final HttpSession session = webRequest.getSession();

        requestContext.setSecurityContext(new SecurityContext() {
            @Override
            public Principal getUserPrincipal() {
                return new PrincipalImpl((String)session.getAttribute("USER_NAME"));
            }

            @Override
            public boolean isUserInRole(String s) {
                return false;
            }

            @Override
            public boolean isSecure() {
                return false;
            }

            @Override
            public String getAuthenticationScheme() {
                return null;
            }
        });
    }
}

Вы также можете зарегистрировать фильтр без использования аннотации @Provider:

import org.glassfish.jersey.server.ResourceConfig;
import javax.ws.rs.ApplicationPath;

/**
 * Root REST resource class.
 */
@ApplicationPath("/rest")
public class RootResource  extends ResourceConfig {
    /**
     * Initializes all resources from REST package.
     */
    public RootResource() {
        packages("com.example.rest");
        register(AuthRequestFilter.class);
    }
}

Примечание: Glassfish 4.0.0 использует старую версию Jersey 2.0. Вам нужно будет обновить Джерси, используя эти советы (доказано, что они не работают) . Или лучше скачать ночную сборку Glassfish 4.0.1., но на данный момент она не полностью стабильна. Я надеюсь, что новая версия будет выпущена в ближайшее время.

person Viacheslav Dobromyslov    schedule 05.11.2013
comment
Работает на здоровье, спасибо! Другие также могут заметить, что если вы не можете использовать аннотации @Provider и т. д. из-за отсутствия поддержки jersey.config.server.provider.packages init-param (например, в WebSphere), то того же можно добиться, передав экземпляр вашего класса провайдера обратно в getSingletons() в вашей реализации. из javax.ws.rs.core.Application - person Brad M; 18.11.2013
comment
Или расширьте ResourceConfig и пропишите там фильтр. - person Viacheslav Dobromyslov; 19.11.2013
comment
Мой ContainerRequestFilter создается один раз во время запуска приложения, поэтому при вызове моего метода filter HttpServletRequest не внедряется. Любая идея, что я делаю неправильно? - person aioobe; 24.08.2015
comment
Когда фильтр зарегистрирован как поставщик, Джерси пытается внедрить атрибуты @Context и терпит неудачу, потому что это происходит вне цепочки запросов. Как зарегистрировать фильтр, не будучи провайдером? - person Singagirl; 14.10.2015
comment
На самом деле я обновил Джерси в соответствии с инструкциями и продолжал получать нули для запроса... только тогда я наткнулся на github.com/dropwizard/dropwizard/issues/1630, который решил проблему... все дело в регистрации вашего фильтра... если вы зарегистрируете экземпляр, а не класс, инъекция не удастся - person GBa; 06.01.2018