Tengo un JAX-RS servicio donde quiero que todos mis usuarios para acceder a mis servicios, pero sólo a aquellos que tienen derechos para ver el resultado. Basado en funciones de seguridad y existentes REINOS y atuhentication métodos no se ajustan a mi requerimiento.

Por ejemplo:

  1. usuario se autentica en un servicio REST y le envío token JWT con su ID de
  2. usuario pide otro recurso y que envía a su JWT con su dni en cada solicitud
  3. Puedo comprobar su id de usuario (a partir de JWT) y si la lógica de negocio devuelve el resultado me envíe de vuelta, otra cosa que enviar vacío o el conjunto de resultados específicos de estado HTTP

Pregunta es: ¿Dónde debo de verificación para la IDENTIFICACIÓN de usuarios, en algunos filtro separado, el contexto de seguridad o en cada DESCANSO de la implementación del método? Cómo proporcionar el RESTO de los métodos con este ID, puede securityContext ser inyectado en cada método después de filtrado de la solicitud por ID?

Estoy usando GlassFish 4.1 y Jersey de JAX-RS aplicación.

OriginalEl autor D00de | 2015-04-21

2 Comentarios

  1. 24

    Puede realizar esta lógica en un ContainerRequestFilter. Es bastante común para manejar personalizada las características de seguridad de aquí.

    Algunas cosas a considerar

    1. La clase debe ser anotado con @Prioridad(Prioridades.AUTENTICACIÓN) por lo que se realiza antes de que otros filtros, si los hubiere.

    2. Usted debe hacer uso de la SecurityContext, en el interior del filtro. Lo que quiero hacer es implementar un SecurityContext. Realmente se puede implementar de la manera que quieras.

    He aquí un ejemplo simple, sin ninguna de la seguridad lógica

    @Provider
    @Priority(Priorities.AUTHENTICATION)
    public class SecurityFilter implements ContainerRequestFilter {
    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
    SecurityContext originalContext = requestContext.getSecurityContext();
    Set<String> roles = new HashSet<>();
    roles.add("ADMIN");
    Authorizer authorizer = new Authorizer(roles, "admin", 
    originalContext.isSecure());
    requestContext.setSecurityContext(authorizer);
    }
    public static class Authorizer implements SecurityContext {
    Set<String> roles;
    String username;
    boolean isSecure;
    public Authorizer(Set<String> roles, final String username, 
    boolean isSecure) {
    this.roles = roles;
    this.username = username;
    this.isSecure = isSecure;
    }
    @Override
    public Principal getUserPrincipal() {
    return new User(username);
    }
    @Override
    public boolean isUserInRole(String role) {
    return roles.contains(role);
    }
    @Override
    public boolean isSecure() {
    return isSecure;
    }
    @Override
    public String getAuthenticationScheme() {
    return "Your Scheme";
    } 
    } 
    public static class User implements Principal {
    String name;
    public User(String name) {
    this.name = name;
    }
    @Override
    public String getName() { return name; }   
    }
    }

    Un par de cosas a notar

    • He creado un SecurityContext
    • He añadido algunas funciones, y los usaron para el isUserInRole método. Esto será utilizado para la autorización.
    • He creado una costumbre User clase que implementa java.security.Principal. Volví a este objeto personalizado
    • Finalmente me puse el nuevo SecurityContext en el ContainerRequestContext

    ¿Y ahora qué? Veamos un sencillo recurso de la clase

    @Path("secure")
    public class SecuredResource {
    @GET
    @RolesAllowed({"ADMIN"})
    public String getUsername(@Context SecurityContext securityContext) {
    User user = (User)securityContext.getUserPrincipal();
    return user.getName();
    }
    }

    Un par de cosas para notar:

    • SecurityContext se inyecta en el método.
    • Tenemos la Principal y echó a User. Así que realmente puede crear cualquier clase que implementa Principal, y el uso de este objeto, sin embargo, te quiero.
    • El uso de la @RolesAllowed anotación. Con Jersey, hay un filtro que controla el SecurityContext.isUserInRole pasando en cada valor de la @RolesAllowed anotación para ver si el Usuario tiene permiso para acceder al recurso.

      Para habilitar esta característica con Jersey, necesitamos registrar el RolesAllowedDynamicFeature

      @ApplicationPath("/api")
      public class AppConfig extends ResourceConfig {
      public AppConfig() {
      packages("packages.to.scan");
      register(RolesAllowedDynamicFeature.class);
      }
      }
    gracias por su respuesta. Pensé que podría hacer uso de ContainerRequestFilter, pero no tengo necesidad de Papeles y SecurityContext para mi requisito. Es demasiado simple para usar filtro de servlets, y para cada solicitud a mi RESTO de los recursos que yo haría referencias y resolución de referencias de envió previamente JWT encabezado, extraer información de usuario a partir de ella y pasar a los métodos del servicio para determinar usuario otorga niveles dentro de cada una de las formas? Esto parece una simple solución pragmática que sólo debería funcionar..
    Bastante más de lo que puedes hacer en un servlet filtro, usted puede hacer en la ContainerRequestFilter. Pero con el último, usted tiene acceso a la camiseta de la aplicación
    gracias, he implementado su solución mediante la Inyección de JWT datos principal de Usuario y, a continuación, traída desde inyectado SecurityContext en cada RESTO método que tengo. Tienen hasta mi voto y aceptación por su ayuda multa de sir.
    Cómo hacerlo en Wildfly 10?
    ¿Cómo crear «Mi Plan», es ese conjunto de roles nombres?

    OriginalEl autor Paul Samsotha

  2. 1

    Yo estaba buscando una solución que es Jersey independiente y trabaja para Wildfly -> encuentra este github ejemplo de aplicación:

    https://github.com/sixturtle/examples/tree/master/jaxrs-jwt-filter

    Debe darle una idea de cómo resolverlo limpio.

    Implementar un JWTRequestFilter que implementa ContainerRequestFilter
    https://github.com/sixturtle/examples/blob/master/jaxrs-jwt-filter/src/main/java/com/sixturtle/jwt/JWTRequestFilter.java

    como se indicó anteriormente y registrar el filtro como resteasy proveedor en web.xml:

    <context-param>
    <description>Custom JAX-RS Providers</description>
    <param-name>resteasy.providers</param-name>
    <param-value>com.sixturtle.jwt.JWTRequestFilter</param-value>
    </context-param>
    <context-param>
    <param-name>resteasy.role.based.security</param-name>
    <param-value>true</param-value>
    </context-param>

    OriginalEl autor max

Dejar respuesta

Please enter your comment!
Please enter your name here