0

我在使用 Pax Web Whiteboard 服务向javax.servlet.Filter通过 CXF 注册的正在运行的 JaxRS 端点注册 a 时遇到问题。我尝试了几种不同的方法,即将过滤器注册为服务,并使用 org.ops4j.pax.web.service.WebContainer 直接注册过滤器。

对于我的测试,我启动了 karaf,并安装了 pax-web、webconsole、cxf 和 pax-web 白板服务。我注册了一个带有蓝图的捆绑包:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
     xmlns:cxf="http://cxf.apache.org/blueprint/core"
     xsi:schemaLocation="
     http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
     http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
     http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
                 ">

     <cxf:bus>
        <cxf:features>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus>

     <jaxrs:server id="webfiltersample" address="/webfilter">
        <jaxrs:serviceBeans>
           <ref component-id="serviceBean" />
        </jaxrs:serviceBeans>
     </jaxrs:server>

     <service id="servletFilterService" interface="javax.servlet.Filter">
        <service-properties>
            <entry key="filter-name" value="BasicWebFilter"/>
            <entry key="urlPatterns" value="/*"/>
            <entry key="initParams" value=""/>
        </service-properties>
    <bean class="test.webfilter.BasicWebFilter"/>
</service>

    <bean id="serviceBean" class="test.webfilter.WebFilterSample" init-method="init" destroy-method="destroy">
    <property name="bundleContext" ref="blueprintBundleContext"/>
    </bean>
</blueprint>

但是,永远不会调用此过滤器。我已经尝试使用 servlet 名称和 urlpatterns,甚至尝试使用 urlpattern /* 然后我尝试了一种稍微不同的方法,从蓝图中删除服务声明,并通过蓝图的 init 方法直接添加过滤器:

public void init(){
    logger.info("Starting Sample");
    filter = new WebFilter();
    ServiceReference<WebContainer> ref = bundleContext.getServiceReference(BasicWebFilter.class);
    WebContainer container = bundleContext.getService(ref);
    logger.info("Registering "+ filter + " with "+ container);
    container.registerFilter(filter, new String[]{"/cxf/*"}, new String[]{""}, null, null);
    bundleContext.ungetService(ref);
    }

正如日志语句所反映的,该方法确实被调用了,但仍然没有执行过滤器。

那么我完全错了这是如何工作的?我的“应用程序”实际上只是注册到 CXF servlet 的一个端点。这部分正在工作,我可以调用其中定义的 REST 服务。但无论我做什么,过滤器都没有执行。我在这里使用一些我不太了解的库(Servlets/Filters、Pax-Web 和 Writeboard 扩展器)我不知道为什么这不起作用?我的猜测是每个包都有不同的httpcontexts,我不能简单地在我自己的测试包中为另一个包(CXF)注册一个过滤器。

如果这是真的,有人可以告诉我如何正确解决这个问题吗?我可以得到 CXF 捆绑包 bundlecontext 并将过滤器注册到那个,但这似乎是一个可怕的可怕黑客。如果不是这样,有人可以告诉我为什么这不起作用吗?

4

2 回答 2

1

你是对的,每个包都应该有它自己的 httpContext。使用 Pax-Web 可以共享 httpContextes。为此,您需要为最初注册 httpContext 的包启用它。尽管在这种情况下,确实是 cxf 包负责处理它。由于共享上下文是仅 pax-web 的功能(直到实现 OSGi R6 的 v6),因此不会将其添加到 cxf,因为 cxf 倾向于依赖最小的可能解决方案,即 HttpService。
基本上,即使可以与不同的包共享 httpContextes,在这种情况下也不可能。

于 2016-03-21T21:03:19.960 回答
0

我建议使用 JAAS 而不是 shiro 作为登录和存储身份验证信息的一种方式。然后,您可以在 shiro 以及其他安全实现中使用它来进行授权。

对于 CXF,有一个 JAASLoginFeature。它可以接收基本身份验证以及 UserNameToken。见https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=42568988

这还具有与标准 karaf 身份验证相同的工作方式的优点。因此,默认情况下,您可以在 etc/users.properties 中定义用户和组,但您也可以将 karaf 附加到 ldap。

如果您使用 blueprint,那么您可以使用 blueprint-authz 使用注释进行基于角色的授权。请参阅https://github.com/apache/aries/tree/trunk/blueprint/blueprint-authzhttps://github.com/apache/aries/blob/trunk/blueprint/blueprint-itests/src/test/java /org/apache/aries/blueprint/itests/authz/testbundle/impl/SecuredServiceImpl.java

于 2016-03-26T09:01:35.193 回答