2012-07-24 39 views
2

我有Axis2 Web服務在應用程序服務器(如JBoss,WebSphere和Weblogic)中運行,直到現在,我在處理請求之前將用戶詳細信息傳遞給請求並進行身份驗證。在Java EE應用服務器上運行的Axis2 WS-Security

下一步是我想將身份驗證位委託給Java EE應用服務器,一旦通過身份驗證,應用服務器就應該通過我將用作上下文的UserPrinciple來執行請求。

我不知道我是否正確提問?我想我將WebContainer身份驗證與WS-Security的東西混合在一起。

任何人都可以請我指向正確的方向與一些文件,我可以參考啓動指南。

+0

讓我重組你的問題......我想用Axis2 Web服務,並希望做一個認證,並通過一個RPINCIPLE我的服務,我將使用該集還我的背景等等方面 – SJunejo 2012-07-25 13:09:14

+0

燦有人請幫我解決這個問題,因爲我找到的所有示例只是解釋如何使用CallBack處理用戶名和密碼,但我找不到有關設置用戶或原理的任何信息,然後我可以稍後使用。 ..有人可以幫忙請...謝謝 – SJunejo 2012-07-26 07:36:34

回答

0

好的,我試過了一個解決方案,它在一定程度上起作用。這裏是細節;

創建TestService的有以下的services.xml

<serviceGroup> 
    <service name="TestWebService" scope="application" targetNamespace="http://TestServiceWs"> 
     <schema schemaNamespace="http://TestServiceWs"/> 
     <description>Test POJO Axis2 AAR deployment</description> 
     <parameter name="ServiceClass">test.TestServiceWS</parameter> 
     <messageReceivers> 
      <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" 
       class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/> 
      <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" 
       class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> 
     </messageReceivers> 
    </service> 

    <module ref="rampart" /> 

    <parameter name="InflowSecurity"> 
     <action> 
     <items>UsernameToken Timestamp</items> 
     <passwordCallbackClass>test.PWHandlerServer</passwordCallbackClass> 
     </action> 
    </parameter> 
</serviceGroup> 

實現PWHandlerServer.java

package test; 

import java.io.IOException; 

import javax.security.auth.callback.Callback; 
import javax.security.auth.callback.CallbackHandler; 
import javax.security.auth.callback.UnsupportedCallbackException; 

import org.apache.ws.security.WSPasswordCallback; 

public class PWHandlerServer implements CallbackHandler { 

    // the username and password we expect incoming WS calls to use 
    private String user = "wsuser"; 
    private String pwd = "wspwd"; 

    public void handle (Callback[] callbacks) throws IOException, UnsupportedCallbackException { 
     for (int i = 0; i < callbacks.length; i++) { 
      if (callbacks[i] instanceof WSPasswordCallback) { 
       WSPasswordCallback pc = (WSPasswordCallback) callbacks[i]; 
       System.out.println("identifier: "+pc.getIdentifer()+", usage: "+pc.getUsage()); 

       if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) { 
        // for passwords sent in digest mode we need to provide the password, 
        // because the original one can't be un-digested from the message 

        // we can throw either of the two Exception types if authentication fails 
        if (! user.equals(pc.getIdentifer())) 
         throw new IOException("unknown user: "+pc.getIdentifer()); 

        // this will throw an exception if the passwords don't match 
        pc.setPassword(pwd); 

       } else if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) { 
        // for passwords sent in cleartext mode we can compare passwords directly 

        if (! user.equals(pc.getIdentifer())) 
         throw new IOException("unknown user: "+pc.getIdentifer()); 

        // we can throw either of the two Exception types if authentication fails 
        if (! pwd.equals(pc.getPassword())) 
         throw new IOException("password incorrect for user: "+pc.getIdentifer()); 
       } 
       // If everything is OK then set the context and move on 
       TestRequestContext ctx = new TestRequestContext(pc.getIdentifer()); 
       TestRequestContext.setRequestContext(ctx); 

      } else { 
       throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback"); 
      } 
     } 
    } 
} 

實現TestRequestContext

package test; 


class TestRequestContext { 
    private final static ThreadLocal<TestRequestContext> currentContext = new ThreadLocal<TestRequestContext>(); 

    public static void setRequestContext(TestRequestContext context) { 
     currentContext.set(context); 
    } 

    public static TestRequestContext getRequestContext() { 
     return currentContext.get(); 
    } 

    public static void clearRequestContext() { 
     currentContext.remove(); 
    } 

    private String userPrincipal; 

    public TestRequestContext(String principal) { 
     this.userPrincipal = principal; 
    } 

    public String getUserPrincipal(){ 
     return this.userPrincipal; 
    } 
} 

現在我SH應該能夠訪問我的Web服務類中的TestRequestContext.getUserPricipal(),並將其傳遞給數據庫以進行事務處理並切換安全上下文。唯一的問題是當我試圖通過SoapUI訪問服務時,它給了我以下例外;

15:07:34,924 INFO [STDOUT] identifier: wsuser, usage: 5 
15:08:48,081 INFO [STDOUT] [ERROR] WSDoAllReceiver: security processing failed (actions mismatch) 
org.apache.axis2.AxisFault: WSDoAllReceiver: security processing failed (actions mismatch) 
     at org.apache.rampart.handler.WSDoAllReceiver.processBasic(WSDoAllReceiver.java:344) 
     at org.apache.rampart.handler.WSDoAllReceiver.processMessage(WSDoAllReceiver.java:86) 
     at org.apache.rampart.handler.WSDoAllHandler.invoke(WSDoAllHandler.java:72) 
     at org.apache.axis2.engine.Phase.invoke(Phase.java:318) 
     at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:254) 
     at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:160) 
     at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:173) 
     at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:144) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:710) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
     at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
     at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182) 
     at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
     at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262) 
     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) 
     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) 
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446) 
     at java.lang.Thread.run(Thread.java:619) 

在了SoapUI,我只是用「驗證」選項卡中設置用戶名和密碼,並調用?在調用之前是否需要設置其他任何東西?

此外,使用ThreadLocal的方法是正確的,或者我可以通過其他方式訪問原理?

謝謝。

+0

我已經排除了異常,並從InflowSecurity的節點中刪除了'Timestamp'。 SoapUI沒有在頭文件中添加時間戳信息,因此失敗了。現在一切正常。 – SJunejo 2012-07-26 14:41:32

0

您也可以通過以下格式獲取以SOAP標頭傳遞的用戶名。在授權之前,您可以在操作中訪問它。您可能不需要TestRequestContext類來存儲用戶名。如果有人不同意,請告訴我。

MessageContext msgContext = MessageContext.getCurrentMessageContext();     
// Getting HttpServletRequest from Message Context 
String username = (String)msgContext 
          .getProperty(RampartMessageData.USERNAME); 
相關問題