2012-03-30 148 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

相关问题