获取 Jersey ResourceFilterFactory 中的实际参数值

发布于 2024-11-14 17:24:38 字数 1246 浏览 1 评论 0原文

我想使用 Jersey 在我的 REST 服务中实现自定义授权。此自定义授权检查方法上的注释以及方法的实际参数 方法接收。

我的 jax-rs 带注释的方法如下所示:

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

@ParseFromQueryString 是一个注释,指示 Jersey(通过可注入提供程序)从查询字符串中解组 Customer。其代码如下所示:

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;
  }
}

@CheckPermission 注释指示我的自定义授权者要检查客户的权限。某些用户可以访问某些客户的信息。类似地,@Requires 注释承担了调用者应具有的角色。这些不是 java 的安全角色(字符串),而是枚举值。

使用 Jersey 的 ResourceDebuggingFilter 作为起点,我已经能够知道将调用哪个方法。但是,我仍然没有弄清楚如何确定哪些参数将实际用于调用该方法。

在我的脑海中,我可以想到两种解决方法:

  1. 使用 Guice + Jersey 的方法拦截器。
  2. QueryStringCustomerInjectable 中编写此逻辑,但这看起来有点草率。这将是一个类做得太多的事情。

然而,我真的希望仅使用 Jersey / JAX-RS 来完成此操作。我感觉我已经很接近了!

有想法吗?指针?

谢谢!

I want to implement custom authorisation in my REST services using Jersey. This custom authorisation inspects annotations on methods as well as the actual parameters that a
method receives.

My jax-rs annotated method looks like:

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

The @ParseFromQueryString is an annotation that indicates Jersey (through an Injectable provider) to unmarshall a Customer from a query string. The code for that looks like:

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;
  }
}

The @CheckPermission annotation indicates my custom authoriser that permissions are to be checked on a customer. Some users have access to information on some customers. Similarly, the @Requires annotation takes a role that the invoker should have. These are not java's security roles (Strings), rather, they are enum values.

Using Jersey's ResourceDebuggingFilter as a starting point, I have been able to get to the point of knowing which method will be invoked. However, I still haven't figured out how to determine which parameters will actually be used to invoke the method.

At the top of my head, I can think of two work arounds:

  1. A Method interceptor using Guice + Jersey.
  2. Code this logic in the QueryStringCustomerInjectable, but this seems a bit sloppy. It would be a class doing too much.

Yet, I would really like to do this using only Jersey / JAX-RS. I feel that I am so close!

Ideas? Pointers?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝礼 2024-11-21 17:24:38

您应该使用FiltersInterceptors来处理有关方法的所有信息。
查看 Jersey 过滤器和拦截器

You should use Filters or Interceptors to handle all the information about method.
see Jersey Filter and Interceptors

若能看破又如何 2024-11-21 17:24:38

对于客户反序列化,您可以实现 javax.ws.rs.ext.ParamConverterProvider 并将其注册到 Jersey 中。然后您可以使用 @QueryParam("customer") 将其注入到您的方法中。它更加灵活,因为您也可以将它与 @BeanParam 或 @PathParam 注释一起使用。

然后您可以使用ContainerRequestFilter。请参阅 jersey 如何执行 Oauth1 例如 OAuth1ServerFilter
接下来您可以做的就是创建一个功能来注册新创建的过滤器(请参阅Oauth1ServerFeature 供参考 - 我现在找不到源代码)。

祝你好运!

For the Customer deserialization you could implement the javax.ws.rs.ext.ParamConverterProvider and register it into Jersey. Then you can inject it into your methods with @QueryParam("customer"). It's a bit more flexible since you can use it also with @BeanParam or @PathParam annotations.

Then you can use the ContainerRequestFilter. See as a reference how jersey does the Oauth1 for example OAuth1ServerFilter.
The next thing you can do is to create maybe a feature which will register the newly created filter (see Oauth1ServerFeature for a reference - I couldn't find the source code right now).

Good luck!

南街九尾狐 2024-11-21 17:24:38

为什么不使用您自己的 Servlet 过滤器,例如

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

 }

最后一步是注册您的 Servlet 过滤器。这是使用 Web 应用程序的 web.xml 完成的。

它会在调用 jersey 资源内的实际代码之前拦截您的 HTTP 请求。

Why not using your own Servlet filter e.g.

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

 }

The last step is to register your servlet filter. This is done using web app's web.xml

It will intercept your HTTP requests before the actual code inside jersey resource is called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文