将SOAP隐式标头添加到WSDL
我的问题与此类似。 How To Pass Soap Header When WSDL Doesn't Define It?但是不同。将SOAP隐式标头添加到WSDL
对于我使用的Web服务,所有方法都需要在SOAP标头内以明文形式发送的身份验证。但是,我的WSDL不包含任何soap头信息。我有一个自定义的平台工具,我必须使用它来从WSDL生成代码。由于标题信息不可用,我无法直接使用生成的类 - 我不想手动修改代码以容纳标题。
我试过在WSDL中指定SOAP头,但是我没有得到正确的名称空间。该WSDL是这里https://stage.totalcheck.sensis.com.au/service/webservice?wsdl和SOAP头如下:
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password>password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
有人能帮助我吗?谢谢!
从概念的角度来看,WSDL不应该定义标题。 WSDL仅用于定义服务的功能方面,如操作,消息,绑定和端点。消息和绑定定义了消息的有效载荷应如何编码和格式化。
但是,SOAP消息的标题不属于有效负载。它们通常用于配置SOAP处理器的非功能属性。安全性是这样一种非功能性财产。有效载荷的功能方面不受影响。只有确保沟通是安全的,WS工具堆栈,而不是服务实现,应该照顾到这一点。
因此,缺失的部分现在是一个标准,允许将一些非功能性需求附加到WSDL服务,以便代码生成器可以自动导出需要发送和/或理解哪些头部以实现非功能性属性 - 不需要手动处理标题字段。该标准存在并被称为WS-Policy。政策通常包含一系列替代方案,这些替代方案公开了供应商和消费者应该能够满足的一组要求。当两种服务应该互相影响时,两种政策都会被采纳,并计算出所谓的“有效政策”。它定义了常见的非功能性需求。通过使用这些信息,提供者和使用者可以自行配置以添加必需的标题,如WS-Security标题。 WS-SecurityPolicy也定义了一组可以使用的策略。 WS-PolicyAttachment定义了如何将这些策略附加到WSDL。
有代码生成器可以处理WS-Policies,例如, Metro或Axis2
头文件元素IS在wsdl/soap模式中定义,所以很难说它不应该被使用:http://schemas.xmlsoap.org/wsdl/soap/你当然可以使用WS-SecurityPolicy,但它很简单一个不同的,尽管更具体的规范。 – 2012-10-15 21:26:02
同意,对于绑定,WSDL [指定](http://www.w3.org/TR/wsdl#_soap:header)如何将某些部分映射到SOAP标头。但是,从概念的角度来看,我认为这是一种不好的做法,因为它将WSDL与特定的绑定绑定在一起。我同意,这个问题也被要求提供特定的SOAP绑定,所以使用头部绑定可能没有问题,但使用WS-Policy是一种更合理的方式(即它表达了非功能性问题“确保请求是认证“与发送特定标头)。在前一种情况下,WS-stack已经知道该怎么做。 – vanto 2012-10-16 17:09:26
尽管我仍然不同意这是“糟糕的做法”(日期可能是一个更好的评估),但我现在看到在这种情况下指向WS-SecurityPolicy是正确的,因为OP中的头文件是WS-Security 。 +1 – 2012-10-16 22:45:47
您可以通过装饰使用SoapHeader属性从wsdl生成的代理类中的方法,将soap头信息添加到方法调用中。
例如,当您“添加Web引用”时,wsdl.exe将为Web服务引用生成客户端代理类Reference.cs。在上面提到的链接https://stage.totalcheck.sensis.com.au/service/webservice?wsdl中,有一条消息suggestAddress,它会在您从Visual Studio添加Web引用时转换为生成的reference.cs客户端代理代码文件中的方法。默认情况下,当这个方法被调用时,肥皂包中将不会有Header。要将SoapHeader添加到此请求的信封中,请将[SoapHeader(“Security”)]属性添加到Reference.cs生成的类中的SuggestAddress方法的顶部,其中“Security”是从SoapHeader基类继承的类。
举例上述要求的安全SOAPHEADER您将创建以下类,
public partial class Security : SoapHeader
{
public UserNameToken UserNameToken { get; set; }
}
public partial class UserNameToken
{
public string UserName { get; set; }
public string Password { get; set; }
}
那么你将装饰在reference.cs的SuggestAddress方法类似其次,
[SoapHeader("Security")]
public suggestAddressesResult suggestAddresses([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] addressSearch search) {
object[] results = this.Invoke("suggestAddresses", new object[] {search});
return ((suggestAddressesResult)(results[0]));
}
这将确保当调用方法suggestAddress时创建的每个信封都包含一个看起来像上面提到的安全标头,
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password>password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
在利用这个问题来帮助自己也承认(如一些人士指出)有问题的标题是那些WS-Security标准
什么是建议地址在这里提到?我不能低头。同时阻碍。我得到错误'SoapwbApp.withHeader'不包含'Invoke'的定义并且没有扩展方法'Invoke'可以被找到(接受第一个参数的类型为“SoapwbApp.withHeader”)(你是否缺少using指令或程序集引用? ) – Sagotharan 2014-10-16 06:16:31
这是哪一种语言? – Marco 2015-02-04 11:25:13
主要适合我。
如果您的代理生成工具是“自定义”的,您可能会切换到自动为WS-Security添加标头,这似乎很合逻辑。但是,如果您使用的是WSDL.exe(Visual Studio中的“添加Web引用”),请改为使用svcutil.exe
(“添加服务引用”)。
如果使用WCF代理,您可以覆盖给定的配置,并允许WCF添加标题为您提供:
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
从那里你可以指定密码:
RemoteSvcProxy.TheirClient client = new RemoteSvcProxy.TheirClient();
client.ClientCredentials.UserName.UserName = "uname";
client.ClientCredentials.UserName.Password = "pwd";
我不知道你的定制工具是什么,但也许它所基于的框架也有类似的配置选项。
'wsse'看起来像通常用于WS-Security的前缀。另外,由于SOAP服务是自描述的,因此我无法找到WSDL中未定义头的有效原因。 – 2011-04-20 14:24:21
这很好。但就像我说的,我不想触摸自动生成的类。我只是修改这个只是为了生成类。 – 2011-04-20 14:47:46
自动生成的类是一个部分类。也许你可以将头添加到另一个类的一部分。当自动生成的文件再次生成时,它不会改变。 – 2011-04-20 14:57:23