jersey seguridad y gestión de sesiones


¿Hay alguna forma de obtener la administración de sesiones o la seguridad programáticamente en Jersey, por ejemplo, la administración de sesiones de aplicaciones web? ¿O las transacciones, las sesiones y la seguridad son manejadas por el contenedor en el que se implementa la aplicación Jersey?

 42
Author: Joshua Taylor, 2009-05-26

7 answers

La administración de sesiones es el ámbito del contenedor en el que se implementa Jersey. En la mayoría de los casos de producción, se implementará dentro de un contenedor que realiza la administración de sesiones.

El siguiente código es un ejemplo simple de un recurso jersey que obtiene el objeto de sesión y almacena valores en la sesión y los recupera en llamadas posteriores.

@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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-28 17:06:20

Pensé que las sesiones es algo que deberíamos nunca usar en Aplicaciones RESTful...

Yegor tiene razón. Nunca debemos mantener el estado en el lado del servidor a la aplicación web convencional. Si desea crear una aplicación orientada a SOA desacoplada, no necesita usar ninguna API/framework para servicios web REST. Si necesita, o desea, mantener el estado global cliente-servidor en el lado del servidor, está construyendo implícitamente lo que podríamos describir como una aplicación [web] orientada a SOA, pero usando Jersey como una especie de marco de desarrollo [web]. Inadvertidamente está torciendo la naturaleza de un servicio web (REST o de otro tipo). Usted puede hacerlo de la manera que se ha sugerido en la primera respuesta, pero no. El resultado final no es un servicio web, solo una aplicación normal construida con herramientas de servicios web.

-_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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-13 09:45:10

Sí es posible. Jersey documentación dice:

La información de seguridad de una solicitud está disponible inyectando un JAX-RS Instancia SecurityContext mediante anotación @ Context. La inyección la instancia de contexto de seguridad proporciona el equivalente de la funcionalidad disponible en la API HttpServletRequest. El contexto de seguridad inyectado depende de la implementación real de la aplicación Jersey. Por ejemplo, para una aplicación Jersey desplegada en un contenedor Servlet, el Jersey SecurityContext encapsulará información desde un contexto de seguridad recuperado de la solicitud de Servlet. En caso de una aplicación de Jersey desplegado en un servidor Grizzly, el SecurityContext devolverá información recuperada de la solicitud de Grizzly.

Ejemplo:

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

O

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

O si desea seguridad fuera de la caja con anotaciones marque estos documentos.

Jersey también le permite personalizar el SecurityContext:

El SecurityContext se puede recuperar directamente de ContainerRequestContext a través del método getSecurityContext (). También puede reemplazar el valor predeterminado de SecurityContext en un contexto de solicitud con un valor personalizado uno usando el método setSecurityContext (SecurityContext). Si establece un custom SecurityContext instance in your ContainerRequestFilter, this la instancia de contexto de seguridad se utilizará para la inyección en JAX-RS campos de clase de recurso. De esta manera se puede implementar una costumbre filtro de autenticación que puede configurar su propio SecurityContext para ser utilizar. Para garantizar la ejecución temprana de su autenticación personalizada solicitar filtro, establecer la prioridad de filtro a AUTENTICACIÓN mediante constantes de Prioridades. Una ejecución temprana de su autenticación filtro se asegurará de que todos los demás filtros, recursos, métodos de recursos y los localizadores de sub-recursos se ejecutarán con su personalizado Instancia SecurityContext.

Vea ejemplos sobre cómo usar filtros de solicitud con Jersey. Y mira mi siguiente ejemplo:

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

¡Atención! Esto se introdujo en Jersey 2.4. Glassfish 4.0.0 utiliza old Jersey 2.0 por lo tanto, tendrá que actualizar Jersey utilizando estos consejos (no se ha demostrado que funcione bien). O la mejor manera es descargar la versión nocturna de Glassfish 4.0.1. pero no es completamente estable en este momento. Espero que la nueva versión sea lanzada pronto.

ACTUALIZACIÓN: Por el momento (2014-02-14) Glassfish 4.0.1 nightly build utiliza Jersey 2.5.1 y la inyección de contexto funciona muy bien.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-14 06:07:19

La respuesta de Jack sobre las sesiones es correcta. Son específicos para el contenedor en el que se ejecuta, aunque la especificación de Servlet al menos le da portabilidad entre los contenedores JavaEE.

En cuanto a la seguridad, al menos tiene la oportunidad de separarla de su código específico de JAX-RS empleando JaaS (Java Authentication and Authorization Service) y un filtro de servlet . El filtro se puede usar para hacer cumplir la autenticación HTTP y, en caso de autenticación exitosa, configurar el sujeto de JaaS con los Directores apropiados. Sus recursos de JAX-RS pueden verificar los Directores apropiados sobre el Tema. Dado que controlas toda la pila, deberías poder confiar en un usuario autenticado en tus recursos (¡pero prueba esto!), y puede hacer cumplir la autorización en función de la operación actual en el código de recurso.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-13 05:31:55

Resolví este problema haciendo que los clientes agregaran el encabezado Authorization y lo probaran en el método REST de la siguiente manera:

@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

De esta manera hay autenticación sin iniciar sesión.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-07 16:11:48

Para la seguridad de Jersey, debe echar un vistazo al soporte de jersey OAuth. OAuth se adapta perfectamente cuando expone la API de su sistema a usuarios externos. Por ejemplo, como la api de 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-14 08:42:36

Puede user @path para agrupar los servicios bajo un solo espacio de nombre. ejemplo .

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

Puede validar su sesión en esta clase de filtro.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-17 08:40:27