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

如何配置WCF服务客户端在消息级别同时使用证书和用户名凭据

解决方案

可以实现单条消息同时附加用户名和证书两种消息级身份凭据,需要结合配置修改和少量客户端代码完成,操作步骤如下:

1 修改app.config配置

方案1:沿用basicHttpBinding加自定义端点行为

在原有system.serviceModel节点下添加行为配置,同时修改终结点关联该行为,完整修改后的配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
    <system.serviceModel>
        <behaviors>
            <endpointBehaviors>
                <behavior name="DualCredentialBehavior">
                    <clientCredentials>
                        <!-- 配置客户端证书,也可以后续在代码中动态指定 -->
                        <clientCertificate 
                            findValue="替换为你的证书指纹" 
                            storeLocation="CurrentUser" 
                            storeName="My" 
                            x509FindType="FindByThumbprint"/>
                    </clientCredentials>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IEfmUserService" messageEncoding="Mtom">
                    <security mode="TransportWithMessageCredential">
                        <message clientCredentialType="Certificate" />
                    </security>
                </binding>
                <binding name="BasicHttpBinding_IEfmUserService1" messageEncoding="Mtom">
                    <security mode="Transport" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="endpointaddress.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IEfmUserService"
                contract="EfmUserService.IEfmUserService" name="BasicHttpBinding_IEfmUserService"
                behaviorConfiguration="DualCredentialBehavior"/>
        </client>
    </system.serviceModel>
</configuration>

方案2:使用自定义绑定(无需额外注入消息头)

如果不想手动构造消息头,可以改用自定义绑定直接支持双重凭据验证:

<bindings>
    <customBinding>
        <binding name="DualAuthBinding">
            <mtomMessageEncoding />
            <security authenticationMode="UserNameForCertificate" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"/>
            <httpsTransport />
        </binding>
    </customBinding>
</bindings>

修改终结点的binding属性为customBinding,bindingConfiguration对应自定义绑定的名称即可。

2 客户端代码配置

如果选用方案1的basicHttpBinding配置,需要在调用服务前手动注入用户名令牌到消息头,示例代码如下:

// 创建服务代理实例
var client = new EfmUserService.IEfmUserServiceClient();

// 若未在配置中指定证书,可通过代码动态设置
// client.ClientCredentials.ClientCertificate.SetCertificate(
//     StoreLocation.CurrentUser,
//     StoreName.My,
//     X509FindType.FindByThumbprint,
//     "你的证书指纹");

// 注入用户名密码凭据到消息安全头
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
    XmlDocument doc = new XmlDocument();
    // 构造WSS标准用户名令牌节点
    XmlElement usernameToken = doc.CreateElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    XmlElement username = doc.CreateElement("wsse", "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    username.InnerText = "你的用户名";
    XmlElement password = doc.CreateElement("wsse", "Password", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    password.SetAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
    password.InnerText = "你的密码";
    usernameToken.AppendChild(username);
    usernameToken.AppendChild(password);

    // 将令牌加入消息头
    MessageHeader securityHeader = MessageHeader.CreateHeader(
        "Security",
        "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
        usernameToken);
    OperationContext.Current.OutgoingMessageHeaders.Add(securityHeader);

    // 调用服务方法
    var response = client.你的服务方法名(参数);
}

注意事项

  • 请确保服务端已经提前配置为同时验证消息中的证书和用户名令牌,否则客户端提交的双重凭据会被服务端忽略或拒绝
  • 若使用HTTP传输而非HTTPS,建议对密码进行哈希加密后再传递,避免明文泄露
  • 证书的指纹输入时要去掉不可见字符,避免匹配失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 13:18:01