【问题标题】:Use wsse security header in soap message (Visual Studio 2015, .Net Framework 4.5)在肥皂消息中使用 wsse 安全标头(Visual Studio 2015,.Net Framework 4.5)
【发布时间】:2016-06-02 14:32:39
【问题描述】:

我想使用 DHL 提供的肥皂服务。你可以在这里找到 wsdl:https://wsbexpress.dhl.com/sndpt/expressRateBook?WSDL

因此,我在 Visual Studio 2015 中针对 .net framework 4.5 创建了一个新的 ClassLibrary。

然后我通过提供 wsdl 地址向创建的项目添加了 Web 引用。我生成了一个包含所有类型和端口的代理文件,但我的第一个问题是,生成的服务从System.Web.Services.Protocols.SoapHttpClientProtocol 扩展。正如我在最近的帖子中所读到的,无法将 wsse 标头获取到该代理。有些帖子建议添加 wse,但似乎较新的 Visual Studio 版本不支持 wse。

我尝试通过 svcutil 生成我的代理。之后,我将生成的 .cs 文件添加到项目中,并将生成的配置文件的内容复制到 app.config。 (因为我删除了网络参考) 现在服务类扩展System.ServiceModel.ClientBase。 (我认为VS中的生成器在内部使用svctool。如果微软希望人们使用wcf,为什么生成器会生成非wcf代理文件。

我还创建了一个 nunit testproject 来测试我的服务,但是如果我将这个版本与 svcutil 生成的版本一起使用,我会收到错误消息。我尝试将其翻译成英语,因为错误以德语显示:

找不到指向服务合同的默认端点元素。我发现这是因为代理在它自己的类库中,因此实际上并没有 app.config。但是我的测试项目也是一个类库。

现在使用需要 ws security 用户名/密码验证的 Web 服务的实际方式是什么?

【问题讨论】:

    标签: web-services wcf soap visual-studio-2015 .net-4.5


    【解决方案1】:


    您可以在兼容模式下添加 Web 参考(我猜您正在这样做)。如果您不是在兼容模式下添加引用,请执行以下操作:

    右键单击引用添加服务引用->高级->添加Web引用(在兼容性部分下方),键入WS的URL并添加引用。

    WSE2.0 扩展作为 Nuget 包提供:

    https://www.nuget.org/packages/Microsoft.Web.Services2/

    在运行以下 nuget 命令的包管理器控制台上安装 nuget 包: 安装包 Microsoft.Web.Services2

    安装 nuget 包后,您需要确保您的项目引用了以下 DLL:

    1. System.Web
    2. System.Web.Services
    3. Microsoft.Web.Services2(安装nuget包后会添加)

    为了使用 WSE2.0 扩展,您需要实际修改添加 WebReference 时创建的 Proxy 类,以从“Microsoft.Web.Services2.WebServicesClientProtocol”而不是“System.Web.Services”继承。协议.SoapHttpClientProtocol”。请注意,如果您更新 WebReference,Proxy 类将再次继承自 SoapHttpClientProtocol。

    将以下 using 子句添加到使用 Proxy 类的代码中:

    using Microsoft.Web.Services2;
    using Microsoft.Web.Services2.Security;
    using Microsoft.Web.Services2.Security.Tokens;
    

    进行此更改后,您的代码应如下所示:

    var token = new UsernameToken("theUser", "thePassword", PasswordOption.SendHashed);
    
    var serviceProxy = new ExpressRateBook.gblExpressRateBook();
    SoapContext requestContext = serviceProxy.RequestSoapContext;
    requestContext.Security.Timestamp.TtlInSeconds = 60;
    requestContext.Security.Tokens.Add(token);
    //The rest of the logic goes here...
    

    我在下面添加了截图供您参考:

    注意:由于我不熟悉您需要使用的实际方法,因此无法测试代码,显示的代码只是我在代理类中看到的示例,请根据您的需要进行更新。如果您按照前面描述的步骤操作,它应该可以正常工作。查看以下链接以获取更详细的说明:

    https://msdn.microsoft.com/en-us/library/ms819938.aspx

    【讨论】:

    • 你不知道你是一个多么了不起的人,这非常感谢你的解决方案
    【解决方案2】:

    您可以配置服务参考以添加安全标头,正如 AW Rowse 在http://cxdeveloper.com/article/implementing-ws-security-digest-password-nonce-net-40-wcf 中描述的那样:

     private void Configure()
        {
            System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
    
            defaultBinding = new BasicHttpBinding
            {
                Security =
                {
                    Mode = BasicHttpSecurityMode.Transport,
                    Transport =
                    {
                        ClientCredentialType = HttpClientCredentialType.Digest
                    }
                }
            };
    
            defaultToken = new UsernameToken(UserName, Password, PasswordOption.SendHashed);
    
            defaultSecurityHeader = MessageHeader.CreateHeader(
              "Security",
              "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
              defaultToken.GetXml(new XmlDocument())
            );
        }
    

    并像这样创建您的客户端/代理:

    public consulta_informacao_respttClient CriaConsultaClinicaClient()
        {
            var client = new consulta_informacao_respttClient(defaultBinding, new EndpointAddress("https://resqa.homologacao.unimed.coop.br/chs-integration-external-services-ptu-clinical/proxy-services/execute-query/execute-query-proxy-service"));
            client.ClientCredentials.UserName.UserName = UserName;
            client.ClientCredentials.UserName.Password = Password;
    
            var scope = new OperationContextScope(client.InnerChannel);
    
            OperationContext.Current.OutgoingMessageHeaders.Add(defaultSecurityHeader);
            return client;
        }
    

    您需要在类中创建的属性是:

    private BasicHttpBinding defaultBinding;
    private UsernameToken defaultToken;
    private MessageHeader defaultSecurityHeader;
    

    您无需在 app/web.config 中配置任何内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      • 2018-09-06
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      相关资源
      最近更新 更多