从 WCF 创建的 ws-security 标头中删除时间戳元素 [英] Remove timestamp element from ws-security headers created by WCF
问题描述
我正在使用来自 WCF 的旧 Java Web 服务,该服务需要以下形式的请求:
I am consuming an old Java web service from WCF that requires the request in the form:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<wsse:Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="xxx" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-ssecurity-utility-1.0.xsd">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
...
</s:Body>
</s:Envelope>
使用以下配置 hack 有效",但我不希望在配置中公开用户名和密码:
Using the following config hack "works" but I don't want the username and password exposed in config:
<binding name="bindingName">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
...
<endpoint address="https://endpoint address"
binding="basicHttpBinding" bindingConfiguration="bindingName"
contract="contract"
name="bindingName">
<headers>
<wsse:Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-8293453" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-ssecurity-utility-1.0.xsd">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</headers>
</endpoint>
我想使用的是以下内容:
What I want to use is something along the lines of:
<binding name="bindingName">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" />
<message clientCredentialType="UserName" />
</security>
</binding>
但这会在安全元素中生成 timestamp
元素,java web 服务依赖于该元素.
But this generates the timestamp
element in the security element, which the java webservice borks on.
我需要做的是从它生成的 XML 中删除时间戳,或者使用某种自定义绑定来为我做这件事.
What I need to do is remove the timestamp from the XML it generates or have some sort of custom binding to do it for me.
我尝试创建自定义凭据,但这仅更改了 usernameToken
元素.
I tried creating custom credentials, but this only changed the usernameToken
element.
我已经看了很多很多 SO 问题(很多来自 2007 年及更早的时候),包括以下内容,但并不高兴:
I have already looked at many, many SO questions (many from 2007 and earlier) including the following with no joy:
删除时间戳元素的最佳、最简单和最优雅的方法是什么.
What is the best, simplest and most elegant way to remove the timestamp element.
提前致谢
推荐答案
在 Kristian Kristensen 关于他在集成到 Java AXIS 1 时遇到的困境的博客文章.X 和 WSS4J 网络服务..比我之前尝试的 hack 简单多了.
Found the answer on Kristian Kristensen's blog post about his woes in integrating to a Java AXIS 1.X and WSS4J web service.. So much simpler and easier than the hacks I was trying previously.
您可以使用 App.config 中的简单自定义绑定来解决此问题:
You can solve this with a simple custom binding in App.config as so:
BUGFIX - 之前版本有一个错误 - 忘记在 httpTransport 中添加证书
BUGFIX - there is a bug in previous version - forgot to add certificate in httpTransport
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBindingName">
<security authenticationMode="UserNameOverTransport" includeTimestamp="false">
<secureConversationBootstrap />
</security>
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport useDefaultWebProxy="false" requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="<endpoint address>"
binding="customBinding"
bindingConfiguration="CustomBindingName"
contract="<contract goes here>"
name="EndpointName" />
</client>
</system.serviceModel>
这给出了正确的 SOAP ws-security 标头,而没有通过调用此代码而混淆 java 服务器的时间戳
This gives the correct SOAP ws-security header without the timestamp that confused the java server just by calling this code
var client = new [clientType]();
client.ClientCredentials.ClientCertificate.Certificate = [certificate];
client.ClientCredentials.UserName.UserName = [UserName];
client.ClientCredentials.UserName.Password = [Password];
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
// TODO wrap in try catch
client.Open();
var result = client.[action](new [RequestType] { ... });
进一步阅读:
- 回答链接的来源 - Kjell-Sverre Jerijærvi 的博客
- 我在哪里找到了实际答案 - Kristian Kristensen 的博客
这篇关于从 WCF 创建的 ws-security 标头中删除时间戳元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!