2013-10-16 35 views
0

我們的應用程序是Web服務的使用者,它要求我們在請求SOAP頭中實現數字簽名(基於X.509)。我們需要在標題標籤如<ds:SignedInfo>, <wsse:BinarySecurityToken>, <ds:CanonicalizationMethod>。它實際上很類似於xml here在Weblogic ServiceControl客戶端上實現數字簽名

現在,作爲客戶我們沒有使用clientgen。服務器方也不希望將其作爲WS-Policy。我在Oracle文檔中搜索了很多內容,但似乎只是假設服務器端需要將此策略強制執行到Web服務。那不可能發生。我們也不能使用客戶端策略,因爲我在Oracle網站上遇到的例子似乎表明,它只適用於通過clientgen生成的客戶端代碼,而我們的代碼使用ServiceControl。

就在今天,我遇到了WSS4J,但我不確定這是否是我正在尋找的答案。它看起來似乎是合理的,但它會在我的情況下工作(考慮到我們有Weblogic ServiceController),而WSS4J的所有示例似乎都使用Axis。

我已經花了最後幾天搜索這個,我越來越沮喪。請幫忙!

感謝, 阿克

回答

0

我都面臨着同樣的問題,最後我們使用了Apache CXF庫創建客戶端,並寫了一些攔截它。在我們的例子中,Web服務具有身份驗證頭,並啓用了X509。以下代碼適用於我,我與您分享:

要離線生成Web服務客戶端,可以將wsdl的xml保存在本地計算機中,然後使用wsconsume/wsdl2java命令創建存根。

在下面的代碼中,如果在SOAP Header中沒有爲Web服務 設置userName和pwd,則可以跳過addSoapHeader部分。

TestClient.java:-

  import java.math.BigDecimal; 
      import java.math.BigInteger; 
      import java.net.Authenticator; 
      import java.net.MalformedURLException; 
      import java.net.URL; 
      import java.util.ArrayList; 
      import java.util.Date; 
      import java.util.GregorianCalendar; 
      import java.util.HashMap; 
      import java.util.Iterator; 
      import java.util.List; 
      import java.util.Map; 
      import java.util.Properties; 
      import javax.net.ssl.HostnameVerifier; 
      import javax.net.ssl.HttpsURLConnection; 
      import javax.net.ssl.SSLSession; 
      import javax.xml.bind.JAXBException; 
      import javax.xml.datatype.DatatypeFactory; 
      import javax.xml.datatype.XMLGregorianCalendar; 
      import javax.xml.namespace.QName; 
      import javax.xml.ws.soap.AddressingFeature; 
      import org.apache.cxf.binding.soap.SoapHeader; 
      import org.apache.cxf.endpoint.Client; 
      import org.apache.cxf.frontend.ClientProxy; 
      import org.apache.cxf.headers.Header; 
      import org.apache.cxf.jaxb.JAXBDataBinding; 
      import org.apache.cxf.ws.addressing.AddressingProperties; 
      import org.apache.cxf.ws.addressing.AttributedURIType; 
      import org.apache.cxf.ws.addressing.EndpointReferenceType; 
      import org.apache.cxf.ws.addressing.VersionTransformer; 
      import org.apache.cxf.ws.addressing.impl.AddressingPropertiesImpl; 
      import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; 
      import org.apache.ws.security.handler.WSHandlerConstants; 
      import com.icbase.tsamplex509.ArrayOfDetailLineItem; 
      import com.icbase.tsamplex509.ArrayOfInventoryLineItem; 
      import com.icbase.tsamplex509.AuthHeader; 
      import com.icbase.tsamplex509.CompleteInventory; 
      import com.icbase.tsamplex509.DetailLineItem; 
      import com.icbase.tsamplex509.InventoryLineItem; 
      import com.icbase.tsamplex509.OrderAdd; 
      import com.icbase.tsamplex509.OrderStatus; 
      import com.icbase.tsamplex509.ResultMessage; 
      import com.icbase.tsamplex509.Service; 
      import com.icbase.tsamplex509.ServiceSoap; 
      import com.st.passport.PassportWebServiceHandler; 
      import com.st.passport.UserInfo; 
      import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl; 

      public class TestClient 
      { 
      private static String proxyUser = "javaMagician"; 
      private static String proxyPassword = "myProxyPws"; 
      private static String proxyHost = "sxf4.dlh.ts.com"; 
      private static String proxyPort = "8080"; 
      private static String wsURL = "http://www.wsdoamin.com/tssamplex509/service.asmx?WSDL"; 


      public static void main(String[] args) throws MalformedURLException, Exception 
      { 
       Authenticator.setDefault(new ANSAuthenticationHandler(proxyUser,proxyPassword)); 
       System.getProperties().put("http.proxyHost", proxyHost); 
       System.getProperties().put("http.proxyPort", proxyPort); 

       Service service = new Service(new URL(wsURL),new QName("http://www.wsdoamin.com/tssamplex509/", "Service")); 

       ServiceSoap port = service.getServiceSoap(new AddressingFeature(true,true)); 

       Client client = ClientProxy.getClient(port); 

       enableWSAddressing(client); 

       enableWsSecurity(client); 

       addSOAPHeader(client); 

       System.out.println("Invoking Web Service ..."); 

       //Calling First Web service 
       CompleteInventory getProductResponse = port.getproduct("*"); 


       System.out.println("Result :: " + getProductResponse.getResultMessage().getResult().name()); 
       System.out.println("Return Message :: " + getProductResponse.getResultMessage().getMessage()); 
       System.out.println("------------------- Inventory -------------------"); 



      } 

      private static void enableWSAddressing(Client client) { 
       AddressingProperties maps = new AddressingPropertiesImpl(); 
       EndpointReferenceType ref = new EndpointReferenceType(); 
       AttributedURIType add = new AttributedURIType(); 
       add.setValue("http://www.wsdoamin.com/tssamplex509/getproduct"); 
       ref.setAddress(add); 
       maps.setReplyTo(ref); 
       maps.setFaultTo(ref); 
       maps.exposeAs(VersionTransformer.Names200408.WSA_NAMESPACE_NAME); 
       client.getRequestContext().put("javax.xml.ws.addressing.context", maps); 
      } 

      private static void enableWsSecurity(Client client) { 
       Properties properties = new Properties(); 
       properties.put("org.apache.ws.security.crypto.provider","org.apache.ws.security.components.crypto.Merlin"); 
       properties.put("org.apache.ws.security.crypto.merlin.keystore.type","jks"); 
       properties.put("org.apache.ws.security.crypto.merlin.keystore.password","changeit"); 
       properties.put("org.apache.ws.security.crypto.merlin.keystore.alias","ts_p&s_ws"); 
       properties.put("org.apache.ws.security.crypto.merlin.file", "cert/TS_P&S_WS.jks"); 
       Map<String, Object> outProps = new HashMap<String, Object>(); 
       outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE); 
       outProps.put(WSHandlerConstants.USER, "ts_p&s_ws"); 
       outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,ANSAuthenticationHandler.class.getName()); 
       outProps.put("cryptoProperties", properties); 
       outProps.put(WSHandlerConstants.SIG_PROP_REF_ID,"cryptoProperties"); 
       outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference"); 
       client.getEndpoint().getOutInterceptors().add(new WSS4JOutInterceptor(outProps)); 
       client.getEndpoint().getOutInterceptors().add(new org.apache.cxf.interceptor.LoggingOutInterceptor()); 
       client.getEndpoint().getInInterceptors().add(new org.apache.cxf.interceptor.LoggingInInterceptor()); 
      } 

      private static void addSOAPHeader(Client client) throws JAXBException { 
       List<Header> headers = new ArrayList<Header>(); 
       AuthHeader authHeader = new AuthHeader(); 
       authHeader.setUsername("ts"); 
       authHeader.setPassword("46u43242bw3670"); 
       SoapHeader tokenHeader = new SoapHeader(new QName("http://www.wsdoamin.com/tssamplex509", "AuthHeader"), authHeader,new JAXBDataBinding(AuthHeader.class)); 
       headers.add(tokenHeader); 
       client.getRequestContext().put(Header.HEADER_LIST, headers); 
      } 

      } 

ANSAuthenticationHandler.java

  import java.io.IOException; 
      import java.net.Authenticator; 
      import java.net.PasswordAuthentication; 
      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 ANSAuthenticationHandler extends Authenticator implements CallbackHandler { 

      private String proxyUser; 
      private String proxyPassword; 

      public ANSAuthenticationHandler() { 
       super(); 
      } 
      public ANSAuthenticationHandler(String proxyUser, String proxyPassword) { 
       super(); 
       this.proxyUser = proxyUser; 
       this.proxyPassword = proxyPassword; 
      } 

       public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException 
       { 
       WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; 
       System.err.println("CallbackHandler providing password for :: "+pc.getIdentifier()); 

       if ("ts_p&s_ws".equals(pc.getIdentifier())) { 
       pc.setPassword("changeit"); 
       } 
       } 

       public PasswordAuthentication getPasswordAuthentication() 
      { 
       System.err.println("Feeding username and password for ["+getRequestingPrompt()+"] to ["+getRequestingHost()+":"+getRequestingPort()+"] for ["+getRequestingScheme()+"] scheme"); 
       return (new PasswordAuthentication(proxyUser, proxyPassword.toCharArray())); 
      } 
      }