以编程方式添加终结点标头安全 WCF

Posted

技术标签:

【中文标题】以编程方式添加终结点标头安全 WCF【英文标题】:Add endpoint header security WCF programmatically 【发布时间】:2011-11-23 13:06:17 【问题描述】:

我有这个 web.config 文件来配置来自外部服务的客户端代理这个服务需要对消息头进行身份验证,我已经在我的 web.config 上很好地配置了该服务,但是现在我正在尝试创建代理使用此代码配置,建议动态更改用户和密码。

<cliente>
    <endpoint address="https://wwwww.hhhahdhadhs.askadadasda" binding="basicHttpBinding" bindingConfiguration="MyConfiguration" contract="PROXY_ACSS_SERVICES.RegistoPrescricaoMedicamentos">
            <headers>
              <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                <wsse:UsernameToken>
                  <wsse:Username>MyUser</wsse:Username>
                  <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">87726655434</wsse:Password>
                </wsse:UsernameToken>
              </wsse:Security>
            </headers>
          </endpoint>
</cliente>

<basicHttpBinding>
<binding name="PrescricaoMedicamentos" 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="Transport">
            <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
            <message clientCredentialType="Certificate" algorithmSuite="Default" />
          </security>
        </binding>
</basicHttpBinding>

我的问题是创建定义用户名和密码的标题,

<headers>


   <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken>
              <wsse:Username>MyUser</wsse:Username>
              <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">87726655434</wsse:Password>
            </wsse:UsernameToken>
          </wsse:Security>
        </headers>  

提前致谢

编辑

Ladislav Mrnka 在我以编程方式创建代理后收到此消息

'请求通道超时后尝试发送 00:00:59.9829990。增加传递给调用的超时值 请求或增加 Binding 上的 SendTimeout 值。时间 分配给该操作的可能是较长时间的一部分 超时。'

这是我的代理配置

   BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
            binding.Name = "PrescricaoMedicamentos";
            binding.CloseTimeout = new TimeSpan(0, 1, 0);
            binding.OpenTimeout = new TimeSpan(0, 1, 0);
            binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
            binding.SendTimeout = new TimeSpan(0, 1, 0);
            binding.AllowCookies = false;
            binding.BypassProxyOnLocal = false;
            binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
            binding.MaxBufferSize = 65536;
            binding.MaxBufferPoolSize = 524288;
            binding.MaxReceivedMessageSize = 65536;
            binding.MessageEncoding = WSMessageEncoding.Text;
            binding.TextEncoding = System.Text.Encoding.UTF8;
            binding.TransferMode = TransferMode.Buffered;
            binding.UseDefaultWebProxy = true;
            binding.ReaderQuotas = new XmlDictionaryReaderQuotas()
                                       
                                           MaxDepth = 32,
                                           MaxStringContentLength = 8192,
                                           MaxArrayLength = 16384,
                                           MaxBytesPerRead = 4096,
                                           MaxNameTableCharCount = 16384
                                       ;

            binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName; 


            return binding;

我想知道是否可以在代码中为所有消息添加静态标头。像 AddressHeader.CreateAddressHeader('authentication header') 之类的东西并将此标头应用于我的 EndpointAddress 配置。这种方法用文字代替了我的第一个代码

<headers>
          <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken>
              <wsse:Username>myusername</wsse:Username>
              <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypass</wsse:Password>
            </wsse:UsernameToken>
          </wsse:Security>
        </headers>

【问题讨论】:

【参考方案1】:

如果服务正确实现了用户名令牌配置文件,请将绑定中的安全设置更改为:

<security mode="TransportWithMessageCredential">
    <message clientCredentialType="UserName" />
</security>

一旦您通过以下方式创建代理集凭据:

proxy.ClientCredentials.UserName.UserName = ...;
proxy.ClientCredentials.UserName.Password = ...;

【讨论】:

我已尝试使用您的建议,但是当尝试连接该服务时,我的客户端应用程序收到此异常“安全处理器无法在消息中找到安全标头。这可能是因为消息是不安全的错误,或者是因为通信双方之间存在绑定不匹配。如果为安全配置了服务并且客户端未使用安全性,则可能会发生这种情况。你能帮我解决这个问题吗!?谢谢 开启message logging 并检查从服务返回的内容。要么是故障,要么是没有时间戳的消息。

以上是关于以编程方式添加终结点标头安全 WCF的主要内容,如果未能解决你的问题,请参考以下文章

从.NET调用WCF服务时如何以编程方式添加soap标头?

在客户端应用程序中,在代码中创建 WCF 终结点配置?

WCF配置文件详解

WCF - WCF基本概念和简单WCF服务端创建

保护来自 Azure 函数的 WCF (asmx) 调用

在 C# 中以编程方式创建 WCF 客户端的标头(wsse)部分