Функции аутентификации GWT RequestFactory

Я использую GWT и RequestFactory в новом проекте, требующем аутентификации.

Где было бы лучше всего добавить функции входа и выхода? в UserRequestContext?

Заранее спасибо.


person Manu    schedule 06.04.2012    source источник


Ответы (1)


Используйте фильтр сервлетов.

Я разделяю вызовы RequestFactory на два потока — один для неаутентифицированных вызовов, а другой — для аутентифицированных. Вот кусок моего web.xml.

<servlet>
    <servlet-name>CustomRequestFactoryServlet</servlet-name>
    <servlet-class>my.server.CustomRequestFactoryServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>CustomRequestFactoryServlet</servlet-name>
    <url-pattern>/gwtRequest</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>CustomRequestFactoryServlet</servlet-name>
    <url-pattern>/gwtRequestAuth</url-pattern>
</servlet-mapping>

Затем я создал фильтр сервлета, который выглядит так:

public class GaeAuthFilter implements Filter
{
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
    {
        UserService userService = UserServiceFactory.getUserService();
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        if (!userService.isUserLoggedIn())
        {
            String returnURI = "/";

            String requestURI = request.getRequestURI();
            String refererURI = request.getHeader("Referer");
            if (requestURI.equals("/gwtRequestAuth"))
            {
                if (refererURI != null)
                    returnURI = refererURI;
            } else
                returnURI = requestURI;

            response.setHeader("login", userService.createLoginURL(returnURI));
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        LoginService.login(request);

        filterChain.doFilter(request, response);
    }
}

Как видите, я установил login http-заголовок с URL-адресом для авторизации веб-страницы.

В клиентском коде я перехватываю его, реализуя свой собственный DefaultRequestTransport, который выглядит так:

public class GaeAuthRequestTransport extends DefaultRequestTransport
{
    private final EventBus eventBus;

    public GaeAuthRequestTransport(EventBus eventBus)
    {
        this.eventBus = eventBus;
    }

    @Override
    protected RequestCallback createRequestCallback(final TransportReceiver receiver)
    {
        final RequestCallback superCallback = super.createRequestCallback(receiver);

        return new RequestCallback()
        {
            public void onResponseReceived(Request request, Response response)
            {
                if (Response.SC_UNAUTHORIZED == response.getStatusCode())
                {
                    String loginUrl = response.getHeader("login");
                    if (loginUrl != null)
                    {
                        receiver.onTransportFailure(new ServerFailure(
                                "Unauthenticated user", null, null, false /* not fatal */));
                        eventBus.fireEvent(new GaeAuthenticationFailureEvent(loginUrl));
                        return;
                    }
                }
                superCallback.onResponseReceived(request, response);
            }

            public void onError(Request request, Throwable exception)
            {
                superCallback.onError(request, exception);
            }
        };
    }
}

Событие Fired обрабатывается в клиентском коде, который направляет браузер по URL-адресу входа.

Вот и все.

person expert    schedule 10.04.2012
comment
Спасибо за Ваш ответ. Я согласен с тем, как вы используете для разделения защищенных и незащищенных данных. Но мой вопрос больше касается расположения этих функций аутентификации. Вы бы порекомендовали добавить их в свой пользовательский EntityProxy или добавить куда-то еще? в выделенном ValueProxy? - person Manu; 17.04.2012
comment
Есть несколько вариантов. У вас может быть отдельная страница входа, как в моем примере выше. Или вы можете создать функцию login()/logout() в вашем интерфейсе RequestContext. Первый вариант более олдскульный, второй вариант более AJAX :) - person expert; 18.04.2012
comment
Спасибо руслан. Хорошо, я должен признать, что мой первый вопрос не очень ясен, но я хочу использовать requestfactory для функций аутентификации. Следовательно, я говорю о вашем втором варианте, и, чтобы быть ясным, я ищу лучшие практики для достижения этого. - person Manu; 19.04.2012
comment
Удачи и не стесняйтесь публиковать здесь больше вопросов по RF :) И не забывайте отмечать ответы людей как правильные (когда они правильные), так это улучшит ваш рейтинг. - person expert; 19.04.2012
comment
Иду сюда с другого вопроса, так что я очень опаздываю на вечеринку. Обратите внимание, что ваш нефильтрованный RequestFactoryServlet будет с радостью обслуживать те же самые данные и методы обслуживания, что и отфильтрованный, поэтому убедитесь, что во всех ваших методах обслуживания вы проверяете аутентифицированного пользователя, иначе вы можете утечь некоторые данные (или, что еще хуже, позволить кому-либо изменить их). !) - person Thomas Broyer; 03.12.2013