从 CXF 拦截器确定目标服务/方法

发布于 2024-10-03 17:54:19 字数 128 浏览 0 评论 0原文

我想为 Apache CXF JAX-RS 实现编写一个拦截器,用于检查特定注释的目标服务/方法,并对该注释进行一些特殊处理。

我似乎在拦截器文档中找不到任何描述如何执行此操作的内容。有人有什么想法吗?

谢谢!

I'd like to write an interceptor for the Apache CXF JAX-RS implementation that inspects the target service/method for a particular annotation and does some special processing for that annotation.

I can't seem to find anything in the interceptor documentation that describes how to do this. Does anyone have any ideas?

Thanks!

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

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

发布评论

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

评论(4

丘比特射中我 2024-10-10 17:54:19

如果拦截器在链中运行得相当晚(例如 USER_LOGICAL
阶段),你应该能够做类似的事情:


Exchange exchange = msg.getExchange();
BindingOperationInfo bop = exchange.get(BindingOperationInfo.class);
MethodDispatcher md = (MethodDispatcher) 
                exchange.get(Service.class).get(MethodDispatcher.class.getName());
Method meth = md.getMethod(bop);

这应该给你绑定的方法,这样你就可以获得声明的
类或注释等...

If the interceptor runs fairly late in the chain (like the USER_LOGICAL
phase), you should be able to do something like:


Exchange exchange = msg.getExchange();
BindingOperationInfo bop = exchange.get(BindingOperationInfo.class);
MethodDispatcher md = (MethodDispatcher) 
                exchange.get(Service.class).get(MethodDispatcher.class.getName());
Method meth = md.getMethod(bop);

That should give you the Method that was bound in so you can get the declared
class or the annotations, etc...

稍尽春風 2024-10-10 17:54:19

啊。我没有指定我正在使用 CXF 的 JAX-RS 部分;不确定这是否会影响丹尼尔·库尔普的答案,但他的解决方案实际上对我不起作用。我相信这是因为 CXF 在处理 JAX-RS 时的做法有所不同。

我遇到了 CXF 的 [JAXRSInInterceptor][1] 的源代码,我在该代码中看到该拦截器将方法信息放入 Exchange 对象中,如下所示:

message.getExchange().put(OperationResourceInfo.class, ori);

...在 UNMARSHAL 阶段,根据 CXF 拦截器文档 发生在 *_LOGICAL 阶段之前。因此,通过编写一个处理 USER_LOGICAL 阶段的拦截器,我可以执行以下操作:

message.getExchange().get(OperationResourceInfo.class)

...访问处理调用的 ServiceMethodClass

Ah. I didn't specify that I was using the JAX-RS part of CXF; not sure if that impacts Daniel Kulp's answer but his solution didn't actually work for me. I believe it is because CXF does things differently when handling JAX-RS.

I came across the source for CXF's [JAXRSInInterceptor][1] and I saw in that code that this interceptor is putting the method info into the Exchange object like so:

message.getExchange().put(OperationResourceInfo.class, ori);

...during the UNMARSHAL phase, which according to the CXF interceptor docs happens before the *_LOGICAL phase. So by writing an Interceptor that handles the USER_LOGICAL phase I can do:

message.getExchange().get(OperationResourceInfo.class)

...to get access in there to the Method and Class<?> of the Service handling the call!

暮年 2024-10-10 17:54:19

根据原始询问者的答案,我想出了这个

public UserContextInterceptor() {
    super(Phase.USER_LOGICAL);
}

@Override
public void handleMessage(Message message) {
    if(StringUtils.isEmpty(getHeader("some-header-name", message))) {
        final Method method = getTargetMethod(message);
        if(isAnnotated(method.getDeclaringClass().getAnnotations()) || isAnnotated(method.getAnnotations())) {
            final Fault fault = new Fault(new LoginException("Missing user id"));
            fault.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
            throw fault;
        }
    }
}

private static Method getTargetMethod(Message message) {
    final Exchange exchange = message.getExchange();
    final OperationResourceInfo resource = exchange.get(OperationResourceInfo.class);
    if(resource == null || resource.getMethodToInvoke() == null) {
        throw new AccessDeniedException("Method is not available");
    }
    return resource.getMethodToInvoke();
}

private static boolean isAnnotated(Annotation[] annotations) {
    for(Annotation annotation : annotations) {
        if(UserRequired.class.equals(annotation.annotationType())) {
            return true;
        }
    }
    return false;
}

Building off the original interrogator's answer, I came up with this

public UserContextInterceptor() {
    super(Phase.USER_LOGICAL);
}

@Override
public void handleMessage(Message message) {
    if(StringUtils.isEmpty(getHeader("some-header-name", message))) {
        final Method method = getTargetMethod(message);
        if(isAnnotated(method.getDeclaringClass().getAnnotations()) || isAnnotated(method.getAnnotations())) {
            final Fault fault = new Fault(new LoginException("Missing user id"));
            fault.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
            throw fault;
        }
    }
}

private static Method getTargetMethod(Message message) {
    final Exchange exchange = message.getExchange();
    final OperationResourceInfo resource = exchange.get(OperationResourceInfo.class);
    if(resource == null || resource.getMethodToInvoke() == null) {
        throw new AccessDeniedException("Method is not available");
    }
    return resource.getMethodToInvoke();
}

private static boolean isAnnotated(Annotation[] annotations) {
    for(Annotation annotation : annotations) {
        if(UserRequired.class.equals(annotation.annotationType())) {
            return true;
        }
    }
    return false;
}
许仙没带伞 2024-10-10 17:54:19

距离接受答案已经有一段时间了。但是,其中提供的一个支持抽象

cxf-rt-core-2.7.3.jar

是 org.apache.cxf.interceptor.security.AbstractAuthorizingInInterceptor

源中的示例摘录可能是一个很好的参考:

protected Method getTargetMethod(Message m) {
    BindingOperationInfo bop = m.getExchange().get(BindingOperationInfo.class);
    if (bop != null) {
        MethodDispatcher md = (MethodDispatcher) 
            m.getExchange().get(Service.class).get(MethodDispatcher.class.getName());
        return md.getMethod(bop);
    } 
    Method method = (Method)m.get("org.apache.cxf.resource.method");
    if (method != null) {
        return method;
    }
    throw new AccessDeniedException("Method is not available : Unauthorized");
}

It has been quite some time since the accepted answer. But there are a few supporting abstractions provided in the

cxf-rt-core-2.7.3.jar

One in there that is provided is org.apache.cxf.interceptor.security.AbstractAuthorizingInInterceptor

This sample excerpt from the source might be a good reference:

protected Method getTargetMethod(Message m) {
    BindingOperationInfo bop = m.getExchange().get(BindingOperationInfo.class);
    if (bop != null) {
        MethodDispatcher md = (MethodDispatcher) 
            m.getExchange().get(Service.class).get(MethodDispatcher.class.getName());
        return md.getMethod(bop);
    } 
    Method method = (Method)m.get("org.apache.cxf.resource.method");
    if (method != null) {
        return method;
    }
    throw new AccessDeniedException("Method is not available : Unauthorized");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文