2011-06-10 9 views
19

Deseo implementar autorizaciones personalizadas en mis servicios REST utilizando Jersey. Esta autorización personalizada inspecciona las anotaciones sobre los métodos, así como los parámetros reales que recibe un método .Obteniendo valores de parámetros reales en Jersey ResourceFilterFactory

Mi método JAX-RS anotada parece:

@GET 
@Path("customers") 
@Requires(Role.CustomerManager) 
public Customer getCustomer(@ParseFromQueryString @CheckPermission final Customer customer) { 
    // ... 
} 

El @ParseFromQueryString es una anotación que indica Jersey (a través de un proveedor inyectable) Resolver referencia a un Customer de una cadena de consulta. El código para que se parece a:

public class QueryStringCustomerInjectable implements Injectable<Customer> { 
    public Customer getValue() { 
    final Customer customer = new Customer(); 
    // ... a UriInfo was injected using the @Context annotation 
    // ... extract parameters from QueryString and use setters 
    return customer; 
    } 
} 

La anotación @CheckPermission indica mi autorizador a medida que los permisos se van a comprobar en un cliente. Algunos usuarios tienen acceso a información sobre algunos clientes. Del mismo modo, la anotación @Requires toma un rol que el invocador debería tener. Estos no son roles de seguridad de Java (Strings), sino que son valores enum.

Usando Jersey ResourceDebuggingFilter como punto de partida, he podido llegar al punto de saber qué método se invocará. Sin embargo, todavía no he descubierto cómo determinar qué parámetros se utilizarán realmente para invocar el método.

En la parte superior de mi cabeza, no puedo pensar en dos arounds de trabajo:

  1. interceptor de un método que utiliza Guice + Jersey.
  2. Codifique esta lógica en el QueryStringCustomerInjectable, pero esto parece un poco descuidado. Sería una clase haciendo demasiado.

Sin embargo, me gustaría realmente gustaría hacer esto utilizando solamente Jersey/JAX-RS. ¡Siento que estoy tan cerca!

Ideas? ¿Punteros?

Gracias!

+0

Todavía no he encontrado una manera sin guin de hacer esto ... Así que está usando guice, o use cxf, que proporciona interceptores y una manera de proporcionar sus propios invocadores. – chahuistle

+0

¿Ha analizado el AOP o simplemente utilizando un filtro de servlet para la solución 1? – hisdrewness

+0

¿Ha intentado utilizar un 'ContainerRequestFilter' e inyectar al cliente en él? No estoy seguro de si '@ BeanParam's está restringido a los recursos o si también pueden ser inyectados en filtros, pero supongo que siempre y cuando el filtro no sea preMatch, debería funcionar. –

Respuesta

0

Para la deserialización del cliente puede implementar el javax.ws.rs.ext.ParamConverterProvider y registrarlo en Jersey. Luego puede inyectarlo en sus métodos con @QueryParam ("cliente"). Es un poco más flexible ya que puede usarlo también con anotaciones @BeanParam o @PathParam.

Luego puede usar el ContainerRequestFilter. Vea como referencia cómo Jersey hace el Oauth1 por ejemplo OAuth1ServerFilter. Lo siguiente que puede hacer es crear tal vez una función que registre el filtro recién creado (consulte Oauth1ServerFeature para obtener una referencia - No pude encontrar el código fuente en este momento).

¡Buena suerte!

0

¿Por qué no utilizar su propio filtro Servlet, p.

public class YourFilter implements Filter { 
    ... 
    @Override 
public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain filterChain) throws IOException, ServletException { 

    // HttpServletRequest httpReq = (HttpServletRequest) request; 
    // HttpServletResponse httpResp = (HttpServletResponse) response; 

    // HttpServletRequest httpReq = (HttpServletRequest) request; 
    // HttpServletResponse httpResp = (HttpServletResponse) response; 
    // ..... httpReq.getUserPrincipal(); 


    // then set what you need using ThreadLocal and use it inside your resource class 

    // do not forget to call 
    filterChain.doFilter(request, response); // at the end of this method 

} 

El último paso es registrar su filtro de servlet. Esto se hace usando web.xml de la aplicación web

Interceptará sus solicitudes HTTP antes de que se llame al código dentro del recurso jersey.

Cuestiones relacionadas