He creado con éxito un servicio web REST con Jersey y lo aseguré a través de anotaciones de seguridad de Java. Se ve algo como esto¿Cómo aseguro los recursos REST para que solo un usuario único de un rol pueda acceder a él?
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
También he fijado un reino con dos papeles: el usuario y admin
conseguí todos los métodos para que sólo los administradores pueden acceder a ellos.
Ahora quiero dar libre de los métodos PUT /users/{id}
y GET /users/{id}
, por lo que los usuarios pueden acceder a sus propios y sólo sus propios recursos.
Ejemplo:
// user anna is logged in and uses the following methods
GET /users/anna // returns 200 OK
GET /users/pete // returns 401 UNAUTHORIZED
ya que no podía encontrar una manera de configurar esto a través de anotaciones, que estoy pensando pasar la solicitud HTTP al método correspondiente para comprobar si el usuario está autorizado a acceder al recurso.
Se vería algo como esto para el método 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();
}
No me gusta este abordaje porque yo creo que habría que añadir el userID
manualy a la sesión.
¿Conoces una manera más elegante de resolver esto?
Si no, ¿cómo se agrega el ID de usuario a la sesión mientras se usa la autenticación de formulario?
EDITAR
Gracias Will y Pavel :) Aquí está mi solución final:
@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);
}
o puede inyectar SecurityContext, consulte http: // jersey. java.net/nonav/apidocs/1.11/jersey/javax/ws/rs/core/SecurityContext.html –
Gracias Will por su visión ayudó mucho. @Pavel, gracias también. Ahora estoy usando el SecurityContext, se ve increíble ahora: D – Zounadire