使用已发行的令牌呼叫WCF服务 [英] Call WCF service with issued token
问题描述
我尝试以下操作:
- WCF客户端调用STS并获取SAML断言
- 客户端使用SAML断言调用服务
现在,我已将上述情况实现为三个LinqPad脚本:client.linq
,sts.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:
- 对
/STS
的第一个请求(符合预期) -
proxy.CrossGatewayQuery
导致对/Service
的三个调用:
- The first request to
/STS
(as expected) 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/Issue
和RSTS/Issue
请求(上述步骤2.1和2.2)? - 如何配置这些片段以完成我想要的工作,即向STS发送一个请求,然后向服务发送一个请求,并传递我从STS获得的SAML断言.
- Why does the WCF client send the
RST/Issue
andRSTS/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屋!