Call WCF service with issued token

荒凉一梦 提交于 2019-12-11 05:18:21

问题


I attempt the following:

  • A WCF client calls a STS and gets SAML assertion
  • The client calls a service using the SAML assertion

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.

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

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. The first request to /STS (as expected)
  2. The proxy.CrossGatewayQuery results in three calls to /Service:

    2.1. A SOAP call with action http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue

    2.2. A SOAP call with action http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue

    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.

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:

  • 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.

回答1:


The first problem was with re negotiating of service credentials.

This change took care of that:

binding.Security.Message.NegotiateServiceCredential = false

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;
}

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

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



来源:https://stackoverflow.com/questions/42342062/call-wcf-service-with-issued-token

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!