You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于指定SOAP请求创建WCF SOAP服务并配置WS-Security?

处理WS-Security的WCF服务实现方案

针对你需要接收指定SOAP请求、以字符串获取Body内容并处理WS-Security UsernameToken的需求,以下是具体实现步骤:

1. 定义服务契约与消息契约

因为要直接获取SOAP Body的原始字符串,我们使用MessageContract来包装请求,同时确保操作的Action匹配请求中的wsa:Action:

using System.ServiceModel;
using System.ServiceModel.Channels;

[ServiceContract(Namespace = "")] // 匹配请求中<ABC>节点的命名空间(此处无命名空间)
public interface ISoapService
{
    [OperationContract(Action = "SoapRQ")] // 严格匹配请求的wsa:Action值
    string ReceiveSoapRequest(SoapRequestMessage request);
}

// 自定义消息契约,用于接收整个SOAP Body内容
[MessageContract]
public class SoapRequestMessage
{
    [MessageBodyMember]
    public string BodyContent; // 后续可自行反序列化该字符串
}

服务实现类中,还可以手动读取WS-Security Header中的用户名:

public class SoapService : ISoapService
{
    public string ReceiveSoapRequest(SoapRequestMessage request)
    {
        // 读取WS-Security Header中的用户名
        var securityHeaderIndex = OperationContext.Current.IncomingMessageHeaders.FindHeader(
            "Security", 
            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
        
        if (securityHeaderIndex != -1)
        {
            var reader = OperationContext.Current.IncomingMessageHeaders.GetReaderAtHeader(securityHeaderIndex);
            reader.ReadToDescendant("Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            string username = reader.ReadElementContentAsString();
            
            // 此处添加用户名验证或业务逻辑
        }

        // 处理BodyContent字符串,比如反序列化<ABC>节点
        return "请求已成功接收";
    }
}

2. 配置WCF支持WS-Security与WS-Addressing

在配置文件(web.config/app.config)中设置绑定、行为与终结点:

绑定配置

使用wsHttpBinding原生支持WS-Security和WS-Addressing,结合HTTPS传输(对应请求中的HTTPS地址):

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="SoapServiceBinding">
        <security mode="TransportWithMessageCredential">
          <message 
            clientCredentialType="UserName" 
            establishSecurityContext="false" 
            negotiateServiceCredential="false"/>
          <!-- 关闭安全上下文协商,适配仅含用户名的Token -->
        </security>
        <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
      </binding>
    </wsHttpBinding>
  </bindings>

服务行为与自定义验证

由于请求中的UsernameToken仅含用户名,需自定义验证器跳过密码校验:

<behaviors>
    <serviceBehaviors>
      <behavior name="SoapServiceBehavior">
        <serviceMetadata httpsGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
        <serviceCredentials>
          <userNameAuthentication 
            userNamePasswordValidationMode="Custom" 
            customUserNamePasswordValidatorType="YourNamespace.CustomUsernameValidator, YourAssembly"/>
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>

自定义验证器实现:

using System.ServiceModel.Security;

namespace YourNamespace
{
    public class CustomUsernameValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            // 根据业务需求验证用户名,此处示例仅校验指定用户名
            if (string.IsNullOrWhiteSpace(userName) || !userName.Equals("soapUserName", StringComparison.OrdinalIgnoreCase))
            {
                throw new FaultException("无效的用户名");
            }
            // 若无需严格校验,可直接跳过判断
        }
    }
}

终结点配置

<services>
    <service name="YourNamespace.SoapService" behaviorConfiguration="SoapServiceBehavior">
      <endpoint 
        address="" 
        binding="wsHttpBinding" 
        bindingConfiguration="SoapServiceBinding" 
        contract="YourNamespace.ISoapService"/>
      <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
    </service>
  </services>
</system.serviceModel>

3. 关键注意事项

  • Action匹配:OperationContract的Action属性必须与请求中的wsa:Action完全一致,否则WCF无法路由到对应操作。
  • 命名空间一致性:服务契约的Namespace要与请求中节点的命名空间匹配,此处请求无命名空间,故留空。
  • HTTPS部署:请求目标为HTTPS地址,服务需部署在HTTPS环境下;测试环境可临时将安全模式改为Message,但生产环境推荐TransportWithMessageCredential。
  • mustUnderstand属性:请求中soapenv:mustUnderstand="0"表示WCF无需强制处理该Header,但仍可通过OperationContext手动读取内容。

内容的提问来源于stack exchange,提问作者Dragon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:15:22