【问题标题】:Call WCF service with issued token使用颁发的令牌调用 WCF 服务
【发布时间】:2017-02-20 10:27:06
【问题描述】:

我尝试以下方法:

  • WCF 客户端调用 STS 并获取 SAML 断言
  • 客户端使用 SAML 断言调用服务

现在我已将上述场景实现为三个 LinqPad 脚本:client.linqsts.linq(自托管 WCF 服务)和 service.linq(自托管 WCF 服务)。他们都可以在https://github.com/codeape2/WCF_STS找到。

我需要一些帮助才能让它工作。

使用client.linq 中的以下代码,我可以调用我的 STS 并获得 SAML 断言:

SecurityToken GetToken()
{
    var binding = new BasicHttpBinding();
    var factory = new WSTrustChannelFactory(binding, stsAddress);
    factory.TrustVersion = TrustVersion.WSTrustFeb2005;

    var rst = new RequestSecurityToken
    {
        RequestType = RequestTypes.Issue,
        KeyType = KeyTypes.Symmetric,
        AppliesTo = new EndpointReference(serviceAddress)
    };
    return factory.CreateChannel().Issue(rst);
}

下一步,我使用以下代码(尝试)调用包含 SAML 断言的服务:

var binding = new WSFederationHttpBinding(WSFederationHttpSecurityMode.Message);
binding.Security.Message.EstablishSecurityContext = false;
var factory = new ChannelFactory<ICrossGatewayQueryITI38>(
    binding, 
    new EndpointAddress(new Uri(serviceAddress), new DnsEndpointIdentity("LocalSTS"))
);

factory.Credentials.SupportInteractive = false;
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = 
    X509CertificateValidationMode.None; 

var proxy = factory.CreateChannelWithIssuedToken(token);
var response = proxy.CrossGatewayQuery(
    Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:ihe:iti:2007:CrossGatewayQuery", "Hello world")
);

接下来会发生什么我完全不明白。我在运行脚本时正在运行提琴手,这就是我所看到的:

  1. /STS 的第一个请求(如预期)
  2. proxy.CrossGatewayQuery 导致对/Service 的三个调用:

    2.1。带有操作 http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue

    的 SOAP 调用

    2.2。带有操作 http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue

    的 SOAP 调用

    2.3。带有操作urn:ihe:iti:2007:CrossGatewayQuery 的最终 SOAP 调用。使用 Fiddler,我注意到 SOAP 安全标头包含第一步中的 SAML 断言。

最终调用导致服务返回 SOAP 错误:无法验证消息中的至少一个安全令牌。保存的 Fiddler 请求/响应日志在这里:https://drive.google.com/file/d/0B-UZlLvBjjB2S050TXRhVEo2Vmc/view?usp=sharing

如果有人能就以下内容启发我,我将不胜感激:

  • 为什么 WCF 客户端将 RST/IssueRSTS/Issue 请求发送到 /Service(上面的步骤 2.1 和 2.2)?
  • 如何配置这些部分以执行我想要的操作,即向 STS 发送一个请求,然后向服务发送一个请求,传递我从 STS 获得的 SAML 断言。

【问题讨论】:

    标签: wcf linqpad ws-trust


    【解决方案1】:

    第一个问题是重新协商服务凭证。

    这个改动解决了这个问题:

    binding.Security.Message.NegotiateServiceCredential = false
    

    然后服务必须启用 WIF 配置:

    host.Credentials.UseIdentityConfiguration = true;
    host.Credentials.IdentityConfiguration = CreateIdentityConfig();
    
    IdentityConfiguration CreateIdentityConfig()
    {
        IdentityConfiguration identityConfig = new IdentityConfiguration(false);
    
        //AUDIENCE URI                
        //the token we receive contains this value, so if do not match we fail
        identityConfig.AudienceRestriction.AllowedAudienceUris.Add(new Uri($"http://{Environment.MachineName}:8000/Service"));
    
        //ISSUER NAME REGISTRY explicit the thumbprint of the accepted certificates, if the token coming in is not signed with any of these certificates then is considered invalid
        var issuerNameRegistry = new ConfigurationBasedIssuerNameRegistry();
        issuerNameRegistry.AddTrustedIssuer("81 5b 06 b2 7f 5b 26 30 47 3b 8a b9 56 bb 9f 9f 8c 36 20 76", "signing certificate sts"); //STS signing certificate thumbprint
        identityConfig.IssuerNameRegistry = issuerNameRegistry;
        identityConfig.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
        return identityConfig;
    }
    

    还有其他更改,github 存储库更新了可在 master 分支中运行的代码。

    感谢 MS 的支持,他们帮我解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 2011-07-13
      • 2011-02-21
      • 2019-05-02
      • 2022-10-15
      • 2015-02-10
      • 1970-01-01
      相关资源
      最近更新 更多