2012-02-23 1 views
5

J'ai créé avec succès un service web REST avec Jersey et l'ai sécurisé via des annotations de sécurité java. Il ressemble à ceciComment sécuriser les ressources REST afin qu'un seul utilisateur d'un rôle puisse y accéder?

GET /users/  // gives me all users 
GET /users/{id} // gives the user identified by {id} 
POST /users/  // creates user 
PUT /users/{id} // updates user identified by {id} 
DELETE /users/{id} // delete user 

J'ai aussi configurer un domaine avec deux rôles: utilisateur et admin

J'ai obtenu toutes les méthodes pour que seuls les administrateurs peuvent y accéder.

Maintenant, je veux donner gratuitement les méthodes PUT /users/{id} et GET /users/{id}, afin que les utilisateurs puissent accéder à leurs propres et seulement leurs propres ressources.

Exemple:

// user anna is logged in and uses the following methods 
    GET /users/anna // returns 200 OK 
    GET /users/pete // returns 401 UNAUTHORIZED 

Comme je ne pouvais pas trouver un moyen de configurer ce à travers des annotations, je pense à passer la requête HTTP vers la méthode pour vérifier si l'utilisateur est autorisé à accéder à la ressource.

Il ressemblerait à quelque chose comme ça pour la méthode GET /users/{id}:

@GET 
@Path("https://stackoverflow.com/users/{id}") 
@RolesAllowed({"admin","user"}) 
@Produces(MediaType.APPLICATION_JSON) 
public Response getUser(
    @PathParam("id") String id, 
    @Context HttpServletRequest req 
) { 
    HttpSession session = request.getSession(false); 

    if (session != null && session.getValue("userID").equals(id)) 
     return getObject(User.class, id); 

    return Response.status(Status.UNAUTHORIZED).build(); 
} 

Je n'aime pas ce aproche parce que je pense que je dois ajouter le userID manualy à la session.

  • Connaissez-vous une façon plus élégante de résoudre ce problème?

  • Si ce n'est pas comment ajouter l'ID utilisateur à la session lors de l'utilisation de l'authentification de formulaire?

EDIT

Merci Will et Pavel :) Voici ma solution finale:

@Context 
private SecurityContext security; 

// ... 
@GET 
@Path("https://stackoverflow.com/users/{id}") 
@RolesAllowed({"admin","user"}) 
@Produces(MediaType.APPLICATION_JSON) 
public Response getUser(@PathParam("id") String id){ 
    if (security.isUserInRole("user")) 
     if (security.getUserPrincipal().getName().equals(id)) 
      return getObject(User.class, id); 
     else 
      return Response.status(Status.UNAUTHORIZED).build(); 
    else 
     return getObject(User.class, id); 
} 

Répondre

2

Dans le HttpServletRequest, vous pouvez appeler getRemoteUser() ou getUserPrincipal() pour obtenir l'identité de l'utilisateur connecté. Vous continuerez alors comme vous le faites en leur permettant spécifiquement ou en leur refusant l'accès à la ressource particulière.Blessed Geek se réfère plus spécifiquement à l'aspect de REST concernant les transactions sans état et l'utilisation de l'authentification HTTP. Bien qu'il s'agisse d'un point important dans la portée plus large d'une architecture REST, il est moins pertinent pour votre question spécifique car vous ne spécifiez pas le type de mécanisme d'authentification que vous utilisez par rapport à votre application Java EE. en Java EE, pas un problème d'application.

Si vous utilisez l'authentification de base, vous utilisez des en-têtes HTTP pour gérer l'authentification et l'autorisation. Si vous utilisez une authentification basée sur un formulaire, le conteneur la gère pour vous via la session de servlet, rendant le service dynamique (puisque les sessions sont un artefact avec état).

Mais cela n'a aucune incidence sur votre question spécifique.

+1

ou vous pouvez injecter SecurityContext, voir http: // jersey. java.net/nonav/apidocs/1.11/jersey/javax/ws/rs/core/SecurityContext.html –

+0

Merci Will pour votre perspicacité a beaucoup aidé. Merci @Pavel aussi je suis maintenant en utilisant le SecurityContext semble génial maintenant: D – Zounadire

0

L'un des aspects les plus importants du déploiement REST est de comprendre le rôle des en-têtes http et les cookies. Pour que REST soit pratique, vous devez déployer une infrastructure d'authentification.

Lire

GWT and Google Docs API.

GWT-Platform login + session management

Lire sur Google Connexion fédérée, OAuth et OpenID.

Certaines de mes explications peuvent être obsolètes si elles ont été postées avant OAuth 2.0.

+0

Salut Geek :) merci pour votre réponse. Peut-être que dans mon cas, c'est un peu exagéré car le service REST n'est utilisé que par un AJAX Web-Fronted qui n'est accessible qu'après vous être connecté. En lisant vos réponses je n'ai pas compris pourquoi j'ai besoin d'un framework authenticaion. Peut-être que vous pourriez me donner un peu plus de perspicacité en allant un peu plus dans mon cas et faire un ou deux exemples pour me convaincre :). En ce qui concerne les en-têtes et le point de cookie, je pourrais aussi avoir besoin d'éclaircissements. – Zounadire

+0

http://stackoverflow.com/questions/9425884/different-browser-means-a-different-client-from-the-same-machine/9426183#9426183 –

Questions connexes