java - example - Obtención de valores de parámetros reales en un ResourceFilterFactory de Jersey
jersey token authentication example (3)
Quiero implementar la autorización personalizada en mis servicios REST utilizando Jersey. Esta autorización personalizada inspecciona las anotaciones en los métodos, así como los parámetros reales que recibe un método.
Mi método anotado jax-rs se parece a:
@GET
@Path("customers")
@Requires(Role.CustomerManager)
public Customer getCustomer(@ParseFromQueryString @CheckPermission final Customer customer) {
// ...
}
La @ParseFromQueryString
es una anotación que indica a Jersey (a través de un proveedor inyectable) que debe desmarcar a un Customer
de una cadena de consulta. El código para eso se ve así:
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 a mi autorizador personalizado que los permisos se deben verificar en un cliente. Algunos usuarios tienen acceso a la información de algunos clientes. Del mismo modo, la anotación @Requires
asume un rol que debe tener el invocador. Estos no son los roles de seguridad de Java (Cadenas), sino que son valores enumerables.
Utilizando el ResourceDebuggingFilter
de Jersey 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, puedo pensar en dos formas de trabajo:
- Un método interceptor utilizando Guice + Jersey.
- Codifique esta lógica en
QueryStringCustomerInjectable
, pero esto parece un poco descuidado. Sería una clase haciendo demasiado .
Sin embargo, realmente me gustaría hacer esto usando solo Jersey / JAX-RS. ¡Siento que estoy tan cerca!
Ideas? Punteros
¡Gracias!
¿Por qué no usar su propio filtro Servlet, por ejemplo?
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 el web.xml de la aplicación web.
Interceptará sus solicitudes HTTP antes de que se llame el código real dentro del recurso jersey.
Debe usar Filters
o Interceptors
para manejar toda la información sobre el método. ver Jersey filtros e interceptores
Para la deserialización del Cliente, puede implementar 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 también puede usarlo con las anotaciones @BeanParam o @PathParam.
Entonces puedes 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!