Question

Y at-il un moyen d'obtenir la gestion ou la sécurité à Jersey séance programatically, par exemple gestion de session application web? Ou sont des transactions, des séances et de sécurité tous traités par le conteneur dans lequel l'application est déployée Jersey?

Était-ce utile?

La solution

La gestion de session est de la compétence du conteneur dans lequel Jersey est déployé. Dans la plupart des cas de production, il sera déployé dans un conteneur qui effectue la gestion de session.

Le code ci-dessous est un exemple simple d'une ressource en jersey qui obtient les valeurs d'objet de session et stocke dans la session et les récupère sur les appels suivants.

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


    }
}

Autres conseils

  

Je pensais que les sessions est quelque chose que nous devrions utiliser jamais   applications RESTful ...

Yegor est juste. Nous ne devons pas jamais maintenir l'état dans le côté serveur a la application web classique. Si vous voulez construire une application orientée SOA découplé vous n'avez pas besoin d'utiliser une API / cadre pour les services Web REST. Si vous avez besoin, ou si vous voulez, pour maintenir l'état global client-serveur dans le côté serveur que vous construisez implicitement ce que nous pourrions décrire comme orientée SOA app [web], mais en utilisant Jersey comme un cadre de développement [web] de toutes sortes. Par inadvertance, vous tordant la nature d'un service Web (REST ou autre). Vous peut le faire de la façon dont il a été suggéré dans la première réponse, mais vous ne doit pas . Le résultat final est pas un service Web, juste une application régulière construit avec les outils de services Web.

-_ o

Oui, il est possible. Jersey documentation dit:

  

Les informations de sécurité d'une demande est disponible en injectant un JAX-RS   par exemple en utilisant l'annotation SecurityContext @Context. le injecté   instance de contexte de sécurité fournit l'équivalent de la fonctionnalité   disponible sur l'API HttpServletRequest. Le contexte de sécurité injecté   dépend du déploiement de l'application Jersey réelle. Par exemple, pour   une application Jersey déployée dans un conteneur de servlet, le Jersey   SecurityContext encapsule les informations d'un contexte de sécurité   extrait de la demande de Servlet. Dans le cas d'une application Jersey   déployé sur un serveur Grizzly, le SecurityContext retournera   informations extraites de la demande Grizzly.

Exemple:

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

ou

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

Ou si vous voulez la sécurité de la boîte avec annotations vérifier ces documents .

Jersey vous permet également de personnaliser le SecurityContext:

  

Le SecurityContext peut être récupéré directement à partir de   ContainerRequestContext via la méthode getSecurityContext (). Vous pouvez aussi   remplacer les SecurityContext par défaut dans un contexte de demande avec une coutume   une aide de la méthode setSecurityContext (SecurityContext). Si vous définissez un   par exemple la coutume SecurityContext dans votre ContainerRequestFilter, ce   instance de contexte de sécurité sera utilisé pour l'injection dans JAX-RS   champs de classe de ressources. De cette façon, vous pouvez mettre en œuvre une mesure   filtre d'authentification que l'installation peut votre propre SecurityContext être   utilisé. Afin d'assurer la début d'exécution de votre authentification personnalisée   filtre de demande, définir la priorité du filtre à l'aide de l'authentification   constantes de priorités. Une première exécution de l'authentification vous   filtre veillera à ce que tous les autres filtres, les ressources, les méthodes de ressources   et localisateurs sous-ressources seront exécutées avec votre commande   par exemple SecurityContext.

Voir sur la façon d'utiliser des filtres de demande avec Jersey . Et vérifier mon exemple suivant:

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

Attention! Ceci a été introduit à Jersey 2.4 . GlassFish 4.0.0 utilise vieux Jersey 2.0 donc vous devrez Jersey mise à niveau en utilisant ces conseils (il est pas prouvé fonctionne bien). Ou la meilleure façon est de télécharger la nightly build de Glassfish 4.0.1 . mais il est pas tout à fait stable pour le moment. J'espère que sortira la nouvelle version bientôt.

Mise à jour: En ce moment (14/02/2014) Glassfish 4.0.1 nightly build utilise Jersey 2.5.1 et injection de contexte fonctionne très bien.

La réponse de Jack sur les sessions est correcte. Ils sont spécifiques au conteneur que vous exécutez dans, bien que la spécification Servlet au moins vous donne la portabilité entre les conteneurs JavaEE.

En ce qui concerne la sécurité, vous avez au moins la possibilité de le séparer de votre code spécifique JAX-RS en utilisant JAA (Java Authentication and Authorization Service) et un filtre de servlet . Le filtre peut être utilisé pour appliquer l'authentification HTTP et, auth réussie, configurer le sujet JAAS avec les directeurs d'école appropriés. Vos ressources JAX-RS peuvent vérifier les directeurs d'école appropriés sur le sujet. Puisque vous contrôlez l'ensemble de la pile, vous devriez pouvoir compter sur un utilisateur authentifié dans vos ressources (mais testons cela!), Et vous pouvez appliquer une autorisation basée sur l'opération en cours dans le code de ressource.

Je l'ai résolu ce problème en demandant aux clients d'ajouter l'en-tête d'autorisation et de le tester dans le Methode REST comme ceci:

@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 cette façon, il est l'authentification sans démarrer une session.

Pour plus de sécurité Jersey vous devriez jeter un oeil sur le soutien maillot OAuth. OAuth convient parfaitement lorsque vous exposez API pour votre système aux utilisateurs externes. Par exemple, comme l'api linkedin

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

Vous pouvez utilisateur @path pour regrouper les services sous un espace de noms unique. exemple .

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

Vous pouvez valider votre session de cette classe de filtre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top