【问题标题】:Unable to add WS-Security header to request built from web reference无法将 WS-Security 标头添加到从 Web 参考构建的请求
【发布时间】:2019-06-12 15:04:12
【问题描述】:

我使用了一个 WebReference 并且接收服务器需要一个 WS-Security 标头:

<wsse:UsernameToken wsu:Id="Example"> 
    <wsse:Username> ... </wsse:Username>
    <wsse:Password Type="..."> ... </wsse:Password>
    <wsse:Nonce EncodingType="..."> ... </wsse:Nonce>
    <wsu:Created> ... </wsu:Created>
</wsse:UsernameToken>

我假设这将包含在 WSDL 中,但是在阅读 this post 之后,我明白逻辑应该分开。

我用来执行请求的客户端类包含一个代理属性IWebProxy:HttpWebClientProtocol。我相信这是我应该提供标题/覆盖信息的地方。请问有人可以确认一下吗?

我也有一些代码可以生成正确的标头。但是我不确定如何在不修改WebReference 的情况下指定这些标题/元素。

public static Tuple<EndpointAddress, BindingElementCollection, string, string> PrepareGlowsAuth(string endpoint)
{
    EndpointAddress soapEndpoint = new EndpointAddress(string.Format("{0}/{1}", (IsProduction ? productionBaseUrl : testingBaseUrl), endpoint));
    BasicHttpsBinding binding = new BasicHttpsBinding();
    binding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
    binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

    BindingElementCollection elements = binding.CreateBindingElements();
    elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;

    return new Tuple<EndpointAddress, BindingElementCollection, string, string>(soapEndpoint, elements, "username", "password");
}

如果有人能指出我正确的方向,将不胜感激!

更新:按照建议后,我看不到 Client 或 Response 类。

【问题讨论】:

标签: c# ws-security soapheader


【解决方案1】:

在不更改客户端类的情况下将凭据注入请求的方法如下:

// Assume that you named your "Connected Service" com.example.foo

foo.bar requestObj= new foo.bar();

// Fill in your request object
bar.FirstName = "Someone";
// etc.

// Set up the authentication using the function you provided
var glowsAuthData = PrepareGlowsAuth("expressRateBook");

// foo.<object name>Client is automatically created, this is the generated
//   proxy class for communicating with the intended web service
foo.barClient client = new foo.barClient(new CustomBinding(glowsAuthData.Item2)
                                         , glowsAuthData.Item1);
client.ClientCredentials.UserName.UserName = glowsAuthData.Item3;
client.ClientCredentials.UserName.Password = glowsAuthData.Item4;

// Use the client to send the request object and populate the response object
// foo.<object name>Response is automatically generated when VS generates 
//   the code for "Connected Service". It also makes it the return type 
//   for foo.barClient.barResponse(foo.bar);
foo.barResponse responseObj = client.barResponse(requestObj);

假设没有例外,responseObj 将包含来自服务器的响应。无需直接修改使用 WSDL 创建的生成客户端。

【讨论】:

  • 非常感谢。看起来很完美。但是有一个问题,我似乎无法在 System.Web.Services 中找到 WebServiceClass。已确保对 dll v4 的引用
  • 所以我有WebService requestObj = new System.Web.Services.WebService(); 但没有WebServiceClassClient client = new WebServiceClassClient。 @Tarek,我必须生成这个类吗?
  • 对我来说不幸的命名,对不起。 requestObj的类型应该是导入WSDL时VS生成的代理类。我将我的命名为 com.dhl.wsbexpress.expressRateBook。我试图保持其通用性,但这样做使用了 .NET 框架使用的名称。
  • 啊,我想我明白了。创建服务引用时,您需要进入高级并选择“始终生成消息合同”。我创建了一个示例应用程序,它可以编译并且应该可以工作。你可以从github.com/tHeCh0s3n0n3/.net-WSSE-example下载它
  • 非常感谢塔雷克!我将 wsdl 添加为 Web 参考而不是服务参考。非常愚蠢的错误!
猜你喜欢
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多