2012-03-30 147 views
1

免責聲明:淨N00BWCFE(含摘要)在WCF .Net C#中 - 一種簡單的方法?

我一直在打我的頭撞在牆上了幾天,現在試圖讓這個外部供應商的Web服務無濟於事保障工作。事實證明,他們使用WSSE消化的安全,這在短,增加了一些像這樣的SOAP頭:

<wsse:UsernameToken wsu:Id="Example-1"> 
    <wsse:Username> ... </wsse:Username> 
    <wsse:Password Type="..."> ... </wsse:Password> 
    <wsse:Nonce EncodingType="..."> ... </wsse:Nonce> 
    <wsu:Created> ... </wsu:Created> 
</wsse:UsernameToken> 

我開始通過添加服務引用,並通過很多很多的博客文章,計算器問題擺弄app.config和代碼。我似乎無法做到。也許這不容易嗎?也許我只是不知道Visual Studio 2010和.Net,我不確定。

這是我停在我的app.config:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="ServiceHttpBinding" closeTimeout="00:01:00" 
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
       allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
       messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
       useDefaultWebProxy="true"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <security mode="TransportWithMessageCredential" /> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="https://vendorurl" 
      binding="basicHttpBinding" bindingConfiguration="ServiceHttpBinding" 
      contract="ContractName" 
      name="ServiceHttpPort"> 
     </endpoint> 
    </client> 
</system.serviceModel> 

和C#:

var someService = new ServiceClient(); 

    someService.ClientCredentials.UserName.UserName = "username"; 
    someService.ClientCredentials.UserName.Password = "passwordgobbletygook/somemorebase64stuff="; 

    #region Begin Magic 
    var elements = someService.Endpoint.Binding.CreateBindingElements(); 

    var securityBindingElement = elements.Find<SecurityBindingElement>(); 
    securityBindingElement.IncludeTimestamp = false; 

    someService.Endpoint.Binding = new CustomBinding(elements); 
    #endregion 

    var response = someService.webMethod(param1, param2, param3, param4); 

    Console.WriteLine(response); 

有趣的是,在廠商的Spec,我發現他們鼓勵使用WSSJ,所以我試了一下(在Java中)和我把它工作在2小時

這是什麼樣子:

public class Test implements CallbackHandler { 

    /** 
    * @param args 
    */ 
    public static void main(final String[] args) throws Throwable { 
     SomeService_Service someService_Service = new SomeService_Service(); 
     SomeService someService = someService_Service.getSomeServiceHttpPort(); 

     BindingProvider bindingProvider = (BindingProvider)someService; 
     Map< String, Object > requestContext = bindingProvider.getRequestContext(); 
     requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://vendorurl"); 

     Client client = ClientProxy.getClient(someService); 
     Endpoint endpoint = client.getEndpoint(); 

     Map< String, Object > outProps = new HashMap< String, Object >(); 
     outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); 
     outProps.put(WSHandlerConstants.USER, "username"); 
     outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); 
     outProps.put(WSHandlerConstants.PW_CALLBACK_REF, new Test()); 

     WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); 
     endpoint.getOutInterceptors().add(wssOut); 

     System.out.println(someService.webMethod(param1, param2, param3, param4)); 
    } 

    public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException { 
     WSPasswordCallback pc = (WSPasswordCallback)callbacks[ 0 ]; 

     // set the password for our message. 
     pc.setPassword("passwordgobbletygook/somemorebase64stuff="); 
    } 
} 

有沒有人在那裏在stackoverflow土地得到了這個工作在.Net \ C#?有什麼明顯的我在這裏失蹤?

+0

我從來沒有得到WS-Security來與non-.Net語言的互操作工作。我們去年開發了一個Web服務,我們的Java合作伙伴在幾周的實驗中無法正確連接,直到我們最終通過HTTPS:S切換到基本身份驗證。我感覺WS-Security的規範對於實際應用來說只是一點點理想主義。 – mellamokb 2012-03-30 19:12:18

+0

有趣的評論@mellamokb。我能夠使它與java一起工作就好,它是我無法工作的.Net代碼。這個特定的供應商(Taleo)與許多其他軟件客戶端進行交互,這就是他們用於安全的原因,所以有人在那裏一定會使它工作。 – javamonkey79 2012-03-30 19:17:48

+0

讓我澄清我的意思。我的意思是在.Net和非.Net語言之間進行互操作。 Java-to-Java在我們發現的時候非常漂亮,而.Net-to-.Net也是如此。但是當我們嘗試.Net到Java的時候,我們遇到了各種模糊的錯誤和條件,並且直到我們放棄它之前,我們纔有了頭。不是說這是不可能的,但我只記得那個項目的一個強烈的痛點。我會很感興趣知道你是如何得到它的工作。我自己是一個網絡服務n00b,所以這可能是其中的一部分:) – mellamokb 2012-03-30 20:03:22

回答

3

在嘗試將基於.NET的組件連接到基於JAVA的SOAP服務時,我們遇到了此問題。我們的解決方案不涉及任何XML構造,並且恕我直言,比我見過的其他任何東西都要乾淨利索。

缺點是您需要下載幷包含一個較舊的可選.NET DLL才能使其工作。好處是代碼非常乾淨,並且自然適合WCF。

基本實現看起來是這樣的:

using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) 
{ 
    //Class from WSE 3.0 
    UsernameToken token = new UsernameToken("MY_USERNAME", "MY_PASSWORD", PasswordOption.SendHashed); 

    //Add Auth to SOAP Header 
    MessageHeader header 
     = MessageHeader.CreateHeader(
     "Security", 
     "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", 
     token.GetXml(new XmlDocument()) 
    ); 

    OperationContext.Current.OutgoingMessageHeaders.Add(header); 

    //Build Request 
    OrgWS.OrganizationDetailsRequest request = new OrgWS.OrganizationDetailsRequest() 
    { 
     ID = 1 
    }; 

    //Send Request 
    OrgWS.OrganizationDetail[] response = client.getOrganizationDetail(request); 

    //Do something with response 
} 

一個完整的解釋可以在這裏找到:http://cxdeveloper.com/article/implementing-ws-security-digest-password-nonce-net-40-wcf

+0

這是我在尋找答案時發現的最好的最乾淨的解決方案。 這個答案真的需要得到更多的讚賞! – 2015-08-18 07:47:41

相關問題