2016-03-21 40 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