Подтвердить что ты не робот

Безопасность и управление сеансом

Есть ли способ получить управление сеансом или безопасность программно в Джерси, например. управление сеансом веб-приложений? Или транзакции, сеансы и безопасность все обрабатываются контейнером, в котором развертывается приложение Джерси?

4b9b3361

Ответ 1

Управление сеансами - это область действия контейнера, в котором задействован Джерси. В большинстве случаев производство будет развернуто в контейнере, который выполняет управление сеансом.

Ниже приведен простой пример ресурса трикотажа, который получает объект сеанса и сохраняет значения в сеансе и извлекает их при последующих вызовах.

@Path("/helloworld")
public class HelloWorld {

    @GET
    @Produces("text/plain")
    public String hello(@Context HttpServletRequest req) {

        HttpSession session= req.getSession(true);
        Object foo = session.getAttribute("foo");
        if (foo!=null) {
            System.out.println(foo.toString());
        } else {
            foo = "bar";
            session.setAttribute("foo", "bar");
        }
        return foo.toString();


    }
}

Ответ 2

Я думал, что сеансы - это то, что мы должны никогда использовать в Приложения RESTful...

Егор прав. Мы никогда не должны поддерживать состояние на стороне сервера в обычном веб-приложении. Если вы хотите создать развязанное SOA-ориентированное приложение, вам не нужно использовать какой-либо API/фреймворк для веб-служб REST. Если вам нужно или хотите поддерживать глобальное состояние клиент-сервер на стороне сервера, вы неявно строите то, что мы можем назвать SOA-ориентированным [веб-приложение], но используем Джерси, как [web]. Неосторожно вы крутите характер веб-службы (REST или иначе). Вы можете сделать это так, как это было предложено в первом ответе, но вы не должны. Конечным результатом является не веб-сервис, а просто обычное приложение, созданное с помощью инструментов веб-сервисов.

-_ o

Ответ 3

Да, это возможно. Джерси documentation говорит:

Информацию о безопасности запроса можно получить, введя JAX-RS Экземпляр SecurityContext с использованием аннотации @Context. Инъецированный Экземпляр контекста безопасности обеспечивает эквивалент функциональности доступный по API HttpServletRequest. Инъекционный контекст безопасности зависит от фактического развертывания приложений в Джерси. Например, для приложение Джерси, развернутое в контейнере Servlet, Джерси SecurityContext будет инкапсулировать информацию из контекста безопасности извлекается из запроса Servlet. В случае заявки Джерси развернутый на сервере Grizzly, SecurityContext вернется информация, полученная из запроса Grizzly.

Пример:

@Path("basket")
public ShoppingBasketResource get(@Context SecurityContext sc) {
    if (sc.isUserInRole("PreferredCustomer") {
        return new PreferredCustomerShoppingBasketResource();
    } else {
        return new ShoppingBasketResource();
    }
}

или

@Path("resource")
@Singleton
public static class MyResource {
    // Jersey will inject proxy of Security Context
    @Context
    SecurityContext securityContext;

    @GET
    public String getUserPrincipal() {
        return securityContext.getUserPrincipal().getName();
    }
}

Или если вы хотите, чтобы безопасность из коробки с аннотациями проверяла эти документы.

Джерси также позволяет настраивать SecurityContext:

. SecurityContext может быть непосредственно извлечен из ContainerRequestContext через метод getSecurityContext(). Вы также можете замените по умолчанию SecurityContext в контексте запроса с помощью настраиваемого один из которых использует метод setSecurityContext (SecurityContext). Если вы установили пользовательский экземпляр SecurityContext в вашем ContainerRequestFilter, это Экземпляр контекста безопасности будет использоваться для инъекций в JAX-RS поля класса ресурсов. Таким образом, вы можете фильтр проверки подлинности, который может настроить ваш собственный SecurityContext для используемый. Чтобы обеспечить раннее выполнение вашей пользовательской аутентификации фильтр запроса, установите приоритет фильтра для АУТЕНТИФИКАЦИИ, используя константы из Приоритетов. Раннее выполнение аутентификации фильтр гарантирует, что все остальные фильтры, ресурсы, методы ресурсов и локаторы подресурсов будут выполняться с вашим пользовательским Экземпляр SecurityContext.

См. примеры использования фильтров запросов с помощью Джерси. И проверьте мой следующий пример:

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;
            }
        });
    }
}

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

UPDATE: На данный момент (2014-02-14) Glassfish 4.0.1 ночная сборка использует Jersey 2.5.1, а использование контекстной инъекции отлично работает.

Ответ 4

Ответ Джека на сеансы правилен. Они специфичны для контейнера, который вы выполняете, хотя спецификация Servlet по крайней мере дает вам переносимость между контейнерами JavaEE.

Что касается безопасности, вы, по крайней мере, имеете возможность отделить его от вашего конкретного кода JAX-RS, используя JaaS (служба проверки подлинности Java и авторизации) и фильтр сервлетов. Фильтр может использоваться для обеспечения аутентификации HTTP и, при успешном завершении работы, настройте объект JaaS с соответствующими Принципами. Ресурсы JAX-RS могут проверять для соответствующих директоров по теме. Поскольку вы контролируете весь стек, вы должны быть в состоянии полагаться на аутентифицированного пользователя в своих ресурсах (но проверить это!), И вы можете принудительно выполнить авторизацию на основе текущей операции в коде ресурса.

Ответ 5

Я решил эту проблему, попросив клиентов добавить заголовок авторизации и протестировать его в методе REST следующим образом:

@GET
@PRODUCES(MediaType.APPLICATION_JSON)
public String returnClients(@Context HTTPServletRequest request(
    String auth = request.getHeader("Authorization");
    Account acc = null;
    if (auth!=null) {
       Account acc = Utils.LoginAccount(auth);
    }
    if (acc == null)
     // not logged in, handle it gracefully

Таким образом выполняется аутентификация без запуска сеанса.

Ответ 6

Для безопасности Джерси вы должны взглянуть на поддержку Джерси OAuth. OAuth отлично подходит, когда вы предоставляете API для вашей системы внешним пользователям. Например, как linkedin api

http://wikis.oracle.com/display/Jersey/OAuth

Ответ 7

Пользователь @path может группировать службы под одним пространством имен. пример.

@Path("/helloworld")
public class HelloWorld {

    @GET
    @Produces("text/plain")
    public String hello() {


        return "";


    }
}
Instead of @Path("/helloworld") use
@Path("admin/helloworld") to expose you class as rest and bind filter on "admin/"
in web.xml as below.

<servlet>
            <servlet-name>jersey-serlvet</servlet-name>
            <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>com.sun.jersey.config.property.packages</param-name>
                <param-value>/</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>jersey-serlvet</servlet-name>
            <url-pattern>/rest/*</url-pattern>
        </servlet-mapping>
         <filter>
            <filter-name>myfilter</filter-name>
            <filter-class>com.Filterclass</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>myfilter</filter-name>
            <url-pattern>/rest/admin/*</url-pattern>
        </filter-mapping> 

    public class Filterclass implements Filter {
       public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain)
                throws IOException, ServletException {
                  try{
                       chain.doFilter(request, response);
                    }catch(Exception e){
                   e.printStackTrace();
                       }
          }
    }

Вы можете проверить ваш сеанс в этом классе фильтра.