bezpieczeństwo jersey i zarządzanie sesjami

Czy istnieje sposób na programowanie zarządzania sesjami lub zabezpieczeniami w Jersey, np. zarządzanie sesjami aplikacji internetowej? A może transakcje, sesje i zabezpieczenia są obsługiwane przez kontener, w którym wdrożona jest aplikacja Jersey?

 42
Author: Joshua Taylor, 2009-05-26

7 answers

Zarządzanie sesją jest zadaniem kontenera, w którym Jersey jest wdrożony. W większości przypadków będzie on wdrażany w kontenerze, który wykonuje zarządzanie sesjami.

Poniższy kod jest prostym przykładem zasobu jersey, który pobiera obiekt sesji i przechowuje wartości w sesji i pobiera je przy kolejnych wywołaniach.

@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();


    }
}
 69
Author: Jack Cox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-28 17:06:20

Myślałem, że sesje to coś, czego nie powinniśmy nigdy używać w Aplikacje relaksacyjne...

Jegor ma rację. Nie powinniśmy nigdy utrzymywać stanu po stronie serwera a la konwencjonalnej aplikacji internetowej. Jeśli chcesz zbudować odsprzęgniętą aplikację zorientowaną na SOA, nie musisz używać żadnego API/frameworka dla Usług Sieciowych REST. Jeśli potrzebujesz lub chcesz, aby utrzymać globalny stan klient-serwer po stronie serwera, domyślnie budujesz to, co moglibyśmy opisać jako aplikacja [web] zorientowana na SOA, ale korzystająca z niej jak swego rodzaju [web] framework programistyczny. Nieumyślnie zmieniasz charakter usługi internetowej(reszta lub w inny sposób). Możesz to zrobić w sposób sugerowany w pierwszej odpowiedzi, ale nie możesz tego zrobić. Efektem końcowym nie jest usługa internetowa, tylko zwykła aplikacja zbudowana z narzędzi serwisów internetowych.

-_o

 23
Author: MAM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-13 09:45:10

Tak, to możliwe. Jersey says:

Informacje o zabezpieczeniu żądania są dostępne poprzez wstrzyknięcie JAX-RS Wystąpienie SecurityContext przy użyciu adnotacji @ Context. The injected security context instance zapewnia odpowiednik funkcjonalności dostępne na HttpServletRequest API. Iniekcyjny kontekst bezpieczeństwa zależy od rzeczywistego wdrożenia aplikacji Jersey. Na przykład dla aplikacja Jersey wdrożona w kontenerze Servlet, Jersey SecurityContext będzie hermetyzować informacje z kontekstu bezpieczeństwa pobrane z prośby o Servlet. W przypadku podania Koszulki wdrożony na serwerze Grizzly, SecurityContext powróci informacje uzyskane z wniosku Grizzly.

Przykład:

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

Lub

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

Lub jeśli chcesz bezpieczeństwa z pola z adnotacjami sprawdzić te dokumenty .

Jersey pozwala również dostosować SecurityContext:

SecurityContext można pobrać bezpośrednio z ContainerRequestContext przy pomocy metody getSecurityContext (). Można również zastąp domyślny SecurityContext w kontekście żądania niestandardowym jeden z wykorzystaniem metody setSecurityContext (SecurityContext). Jeśli ustawisz niestandardowe wystąpienie SecurityContext w ContainerRequestFilter, to instancja kontekstu bezpieczeństwa zostanie użyta do wtrysku do JAX-RS pola klasy zasobów. W ten sposób możesz zaimplementować niestandardowe filtr uwierzytelniania które mogą skonfigurować własne SecurityContext być używany. Aby zapewnić wczesne wykonanie uwierzytelniania niestandardowego request filter, Ustaw priorytet filtra na uwierzytelnianie za pomocą stałe od priorytetów. Wczesne wykonanie uwierzytelniania użytkownika filtr zapewni, że wszystkie inne filtry, zasoby, metody zasobów i sub - resource locators wykonają z niestandardowych Instancja SecurityContext.

Zobacz przykłady użycia filtrów żądań z Jersey . Oraz sprawdź mój następujący przykład:

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;
            }
        });
    }
}
Uwaga! To zostało wprowadzone w Jersey 2.4. Glassfish 4.0.0 używa old Jersey 2.0, dlatego będziesz musiał uaktualnić Jersey używając tych wskazówek (nie udowodniono, że działa dobrze). Albo lepszym sposobem jest pobranie nocnej kompilacji Glassfish 4.0.1. ale w tej chwili nie jest całkowicie stabilny. Mam nadzieję, że nowa wersja ukaże się wkrótce.

Aktualizacja: W tej chwili (2014-02-14) Glassfish 4.0.1 nightly build używa Jersey 2.5.1 i context injection działa świetnie.

 14
Author: Viacheslav Dobromyslov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 06:07:19

Odpowiedź Jacka na temat sesji jest prawidłowa. Są one specyficzne dla kontenera, w którym się uruchamia, chociaż Specyfikacja serwletów przynajmniej daje możliwość przenoszenia między kontenerami JavaEE.

Jeśli chodzi o bezpieczeństwo, masz przynajmniej możliwość oddzielenia go od kodu specyficznego dla JAX - RS poprzez zastosowanie JaaS (Java Authentication and Authorization Service) i filtra serwletów . Filtr może być użyty do wymuszenia uwierzytelniania HTTP i, po pomyślnym auth, skonfigurowania tematu JaaS z odpowiednimi zleceniodawcami. Twoje zasoby JAX - RS mogą sprawdzić odpowiednich zleceniodawców na ten temat. Ponieważ kontrolujesz cały stos, powinieneś móc polegać na uwierzytelnionym użytkowniku w swoich Zasobach (ale przetestuj to!), i możesz wymusić autoryzację na podstawie bieżącej operacji w kodzie zasobu.

 6
Author: StevenC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-13 05:31:55

Rozwiązałem ten problem, każąc klientom dodać nagłówek autoryzacji i przetestować go w pozostałej metodzie w następujący sposób:

@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

W ten sposób odbywa się uwierzytelnianie bez rozpoczynania sesji.

 4
Author: Ron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-07 16:11:48

Dla Jersey security należy spojrzeć na wsparcie jersey OAuth. OAuth doskonale pasuje, gdy wystawiasz API dla Twojego systemu zewnętrznym użytkownikom. Na przykład jak api linkedin

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

 3
Author: abovesun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 08:42:36

Możesz user @ path grupować usługi pod pojedynczą przestrzenią nazw. przykład .

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

Możesz zweryfikować swoją sesję w tej klasie filtrów.

 2
Author: ThmHarsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-17 08:40:27