WCF:将Nonce添加到UsernameToken

Ada*_*igh 24 c# wcf web-services

我正在尝试连接到用Java编写的Web服务,但有些东西我无法弄清楚.

使用WCF和customBinding,几乎所有内容似乎都很好,除了SOAP消息的一部分,因为它缺少Nonce和Created部分节点.显然我错过了一些东西,所以如果你能指出我正确的方向,那就非常感激了.

这是自定义绑定:

<binding name="CustomHTTPBinding">
    <security includeTimestamp="false" authenticationMode="UserNameOverTransport" defaultAlgorithmSuite="Basic256" requireDerivedKeys="True"
              messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
    </security>
    <textMessageEncoding maxReadPoolSize="211" maxWritePoolSize="2132" messageVersion="Soap11"
                         writeEncoding="utf-8"/>
    <httpsTransport />
</binding>
Run Code Online (Sandbox Code Playgroud)

这是消息的相关部分:

<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <o:UsernameToken u:Id="uuid-c306efd1-e84c-410e-a2ad-1046b368582e-1">
        <o:Username>
            <!-- Removed-->
        </o:Username>
        <o:Password>
            <!-- Removed-->
        </o:Password>
    </o:UsernameToken>
</o:Security>
Run Code Online (Sandbox Code Playgroud)

这就是它的外观:

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
 <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-25763165">
    <wsse:Username>..</wsse:Username>
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">..</wsse:Password>
    <wsse:Nonce>6ApOnLn5Aq9KSH46pzzcZA==</wsse:Nonce>
    <wsu:Created>2009-05-13T18:59:23.309Z</wsu:Created>
 </wsse:UsernameToken>
</wsse:Security>
Run Code Online (Sandbox Code Playgroud)

所以问题是:我如何在安全部分中引入Nonce和Created元素?

Bro*_*ies 21

为了创建现时,我不得不改变一些事情

首先,在我的配置中添加了自定义绑定

<system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="myCustomBindingConfig">
          <security includeTimestamp="false" 
                    authenticationMode="UserNameOverTransport" 
                    defaultAlgorithmSuite="Basic256" 
                    requireDerivedKeys="true"
                    messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
          </security>
          <textMessageEncoding messageVersion="Soap11"></textMessageEncoding>
          <httpsTransport maxReceivedMessageSize="2000000000" />
        </binding>
      </customBinding>
    </bindings>
</system.serviceModel>

<client>
    <endpoint address="https://..." [other tags] 
        binding="customBinding" bindingConfiguration="OrangeLeapCustomBindingConfig"/>
</client>
Run Code Online (Sandbox Code Playgroud)

然后,在这里找到这个代码:http: //social.msdn.microsoft.com/Forums/en-US/wcf/thread/4df3354f-0627-42d9-b5fb-6e880b60f8ee 并修改它以创建nonce(只是随机hash,base-64编码)

protected override void WriteTokenCore(System.Xml.XmlWriter writer, System.IdentityModel.Tokens.SecurityToken token)
{
    Random r = new Random();
    string tokennamespace = "o";
    DateTime created = DateTime.Now;
    string createdStr = created.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
    string nonce = Convert.ToBase64String(Encoding.ASCII.GetBytes(SHA1Encrypt(created + r.Next().ToString())));
    System.IdentityModel.Tokens.UserNameSecurityToken unToken = (System.IdentityModel.Tokens.UserNameSecurityToken)token;
    writer.WriteRaw(String.Format(
    "<{0}:UsernameToken u:Id=\"" + token.Id + "\" xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" +
    "<{0}:Username>" + unToken.UserName + "</{0}:Username>" +
    "<{0}:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">" +
    unToken.Password + "</{0}:Password>" +
    "<{0}:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" +
    nonce + "</{0}:Nonce>" +
    "<u:Created>" + createdStr + "</u:Created></{0}:UsernameToken>", tokennamespace));
}

protected String ByteArrayToString(byte[] inputArray)
{
    StringBuilder output = new StringBuilder("");
    for (int i = 0; i < inputArray.Length; i++)
    {
    output.Append(inputArray[i].ToString("X2"));
    }
    return output.ToString();
}
protected String SHA1Encrypt(String phrase)
{
    UTF8Encoding encoder = new UTF8Encoding();
    SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
    byte[] hashedDataBytes = sha1Hasher.ComputeHash(encoder.GetBytes(phrase));
    return ByteArrayToString(hashedDataBytes);
}
Run Code Online (Sandbox Code Playgroud)


Reb*_*cca 11

我有同样的问题.我使用a MessageInspector来代替自定义令牌序列化程序UsernameTokenBeforeSendRequest方法中添加正确的.然后我使用自定义行为来应用修复.

在我的博客文章中记录整个过程(带有演示项目)在WCF客户端代理中支持WS-I Basic Profile Password Digest.或者,您只需阅读PDF即可.

如果您想跟进我的进展到解决方案,您将在StackOverflow上找到它,标题为" WCF客户端使用WS-Security UsernameToken PasswordDigest身份验证方案消耗Axis 2 Web服务时出错 ":


Lad*_*nka 7

本文提供了将UserNameToken Profile与消化密码完全集成到WCF安全管道中的示例.


Mat*_*emp 7

值得指出的是,Rick Strahl做了一篇博客文章(他引用了这个问题),在那里他非常清楚地解释了这一点,并为密码和PasswordDigest提供了解决方案.

我发布这篇文章是因为我最初发现这篇文章,并不能真正遵循它,并且很晚才发现Rick的帖子.这可能会节省一些人的时间.

WCF WSSecurity和WSE Nonce身份验证