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

.NET Core连接STS签发令牌认证的WCF服务方案咨询

.NET Core连接采用STS IssuedToken认证的WCF服务可行方案

由于.NET Core官方WCF客户端对消息安全场景的支持有限,针对你的STS IssuedTokenOverTransport认证场景,可通过手动实现STS令牌获取+自定义SOAP请求的方式完成对接,以下是具体方案:

核心思路

  1. 绕过.NET Core WCF客户端的限制,直接向STS服务发送请求获取SAML令牌
  2. 将获取到的SAML令牌添加到目标WCF服务的SOAP安全头中
  3. 通过HttpClient发送带客户端证书和安全头的SOAP请求完成服务调用

具体实现步骤

1. 加载客户端证书

首先加载用于TLS认证的X509证书:

var clientCert = new X509Certificate2(
    @"XXX.pfx", 
    "123", 
    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet
);

2. 手动向STS请求SAML令牌

构造符合STS要求的SOAP请求,通过HttpClient发送请求并解析返回的SAML令牌(以WSO2 Carbon STS为例):

private static string GetSamlTokenFromSts(
    string stsUrl, 
    string username, 
    string password, 
    X509Certificate2 clientCert)
{
    // 构造STS的SOAP请求(需根据STS的WSDL调整格式)
    var soapRequest = $@"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:wsa=""http://www.w3.org/2005/08/addressing"" xmlns:wst=""http://docs.oasis-open.org/ws-sx/ws-trust/200512"">
        <soapenv:Header>
            <wsa:Action>http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</wsa:Action>
            <wsa:To>{stsUrl}</wsa:To>
        </soapenv:Header>
        <soapenv:Body>
            <wst:RequestSecurityToken>
                <wst:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType>
                <wst:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</wst:TokenType>
                <wsp:AppliesTo xmlns:wsp=""http://schemas.xmlsoap.org/ws/2004/09/policy"">
                    <wsa:EndpointReference>
                        <wsa:Address>https://XXXXX/services/Secured</wsa:Address>
                    </wsa:EndpointReference>
                </wsp:AppliesTo>
                <wst:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</wst:KeyType>
            </wst:RequestSecurityToken>
        </soapenv:Body>
    </soapenv:Envelope>";

    var handler = new HttpClientHandler();
    handler.ClientCertificates.Add(clientCert);
    
    // 设置Basic认证(对应STS绑定中的UserNameOverTransport)
    var authBytes = Encoding.ASCII.GetBytes($"{username}:{password}");
    var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authBytes));

    using (var client = new HttpClient(handler))
    {
        client.DefaultRequestHeaders.Authorization = authHeader;
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/soap+xml"));
        
        var content = new StringContent(soapRequest, Encoding.UTF8, "application/soap+xml");
        var response = client.PostAsync(stsUrl, content).Result;
        response.EnsureSuccessStatusCode();
        
        var responseXml = response.Content.ReadAsStringAsync().Result;
        var xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(responseXml);
        
        // 解析XML获取SAML令牌节点
        var nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
        nsManager.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
        var tokenNode = xmlDoc.SelectSingleNode("//wsse:BinarySecurityToken", nsManager);
        
        return tokenNode?.InnerText;
    }
}

3. 构造并发送目标WCF服务请求

将获取到的SAML令牌添加到SOAP安全头中,发送请求到目标服务:

private static void CallWcfService(
    string serviceUrl, 
    string samlToken, 
    X509Certificate2 clientCert)
{
    // 构造目标服务的SOAP请求(需根据服务WSDL调整参数)
    var soapRequest = $@"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:guv=""GuvenliOdemeServis"">
        <soapenv:Header>
            <wsse:Security xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"" xmlns:wsu=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"">
                <wsse:BinarySecurityToken 
                    EncodingType=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"" 
                    ValueType=""http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"" 
                    wsu:Id=""SAMLToken"">{samlToken}</wsse:BinarySecurityToken>
            </wsse:Security>
        </soapenv:Header>
        <soapenv:Body>
            <guv:EOdemeSaticiKaydet>
                <!-- 替换为实际请求参数 -->
                <!-- <guv:param1>value1</guv:param1> -->
            </guv:EOdemeSaticiKaydet>
        </soapenv:Body>
    </soapenv:Envelope>";

    var handler = new HttpClientHandler();
    handler.ClientCertificates.Add(clientCert);

    using (var client = new HttpClient(handler))
    {
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
        var content = new StringContent(soapRequest, Encoding.UTF8, "text/xml");
        
        var response = client.PostAsync(serviceUrl, content).Result;
        response.EnsureSuccessStatusCode();
        
        var responseXml = response.Content.ReadAsStringAsync().Result;
        // 解析响应结果,处理业务逻辑
        Console.WriteLine("服务调用响应:" + responseXml);
    }
}

4. 主函数调用流程

static void Main(string[] args)
{
    var username = "your_username";
    var password = "your_password";
    var stsUrl = "https://XXXX/services/wso2carbon-sts";
    var serviceUrl = "https://XXXXX/services/Secured";
    
    // 设置TLS版本匹配.NET Framework客户端
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    
    var clientCert = new X509Certificate2(
        @"XXX.pfx", 
        "123", 
        X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet
    );

    // 获取SAML令牌
    var samlToken = GetSamlTokenFromSts(stsUrl, username, password, clientCert);
    if (string.IsNullOrEmpty(samlToken))
    {
        Console.WriteLine("获取STS令牌失败");
        return;
    }

    // 调用目标WCF服务
    CallWcfService(serviceUrl, samlToken, clientCert);
}

注意事项

  • SOAP请求格式需严格匹配STS和目标服务的WSDL定义,可使用抓包工具获取.NET Framework客户端的请求作为参考
  • 解析XML时需正确处理命名空间,避免节点找不到的问题
  • 客户端证书加载时若遇到权限问题,可调整X509KeyStorageFlags参数
  • 确保TLS版本与服务端要求一致(示例中为TLS1.2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:00:56