2016-03-21 35 views
0

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

对于我的测试,我启动了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扩展器),我不知道为什么这不起作用?我的猜测是每个bundle都有不同的httpcontexts,并且我不能在我自己的测试包中简单地为另一个bundle(CXF)注册一个过滤器。

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

+0

我不确定是否有使用过滤器的良好解决方案。也许还有另一种解决方案。你想用过滤器达到什么目的? –

+0

基本上,长期目标是四郎安全。但是我将同时拥有CXF和其他一些端点类型,所以不必为每个端点做一个破解:) –

回答

1

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

+0

所以,这样做的方式很可能是一个与shiro集成的CXF拦截器我猜。 –

0

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

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

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

如果您使用蓝图,那么您可以使用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