使用已发行的令牌呼叫WCF服务 [英] Call WCF service with issued token

查看:99
本文介绍了使用已发行的令牌呼叫WCF服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试以下操作:

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

现在,我已将上述情况实现为三个LinqPad脚本:client.linqsts.linq(托管WCF服务)和service.linq(托管WCF服务).它们都可以在 https://github.com/codeape2/WCF_STS

Now I have implemented the scenario above as three LinqPad scripts: client.linq, sts.linq (self hosted WCF service) and service.linq (self hosted WCF service). They can all be found at https://github.com/codeape2/WCF_STS

我需要一些帮助使其正常工作.

I need some help getting this to work.

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

Using the following code in client.linq, I am able to call my STS and get a SAML assertion:

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断言的服务:

Next step, I use the following code to (attempt to) call my service with the SAML assertion included:

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")
);

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

What happens next I totally do not understand. I have fiddler running when I run the script, and here's what I see:

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

  1. The first request to /STS (as expected)
  2. The proxy.CrossGatewayQuery results in three calls to /Service:

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

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

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

2.3. A final SOAP call with action urn:ihe:iti:2007:CrossGatewayQuery. Using Fiddler, I notice that the SOAP security header includes the SAML assertion from step one.

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

The final call results in a SOAP fault back from the service: At least one security token in the message could not be validated. The saved Fiddler request/response log is here: https://drive.google.com/file/d/0B-UZlLvBjjB2S050TXRhVEo2Vmc/view?usp=sharing

如果有人可以启发我以下几点,我将不胜感激:

If anyone could enlighten me regarding the following, I would be very grateful:

  • 为什么WCF客户端向/Service发送RST/IssueRSTS/Issue请求(上述步骤2.1和2.2)?
  • 如何配置这些片段以完成我想要的工作,即向STS发送一个请求,然后向服务发送一个请求,并传递我从STS获得的SAML断言.
  • Why does the WCF client send the RST/Issue and RSTS/Issue requests to the /Service (steps 2.1 and 2.2 above) ?
  • How can I configure the pieces to do what I want, i.e. send one request to the STS and then one request to the service, passing the SAML assertion I got from the STS.

推荐答案

第一个问题是与服务凭证的重新协商.

The first problem was with re negotiating of service credentials.

此更改解决了这一问题:

This change took care of that:

binding.Security.Message.NegotiateServiceCredential = false

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

Then the service had to enable WIF configuration:

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分支中工作的代码.

There were other changes too, the github repo has updated code that works in the master branch.

感谢MS支持人员帮助我解决了这个问题.

Thanks to MS support who walked me through figuring this out.

这篇关于使用已发行的令牌呼叫WCF服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆