Позвонить в сервис WCF с выданным токеном

Я пытаюсь сделать следующее:

  • Клиент WCF вызывает STS и получает утверждение SAML
  • Клиент вызывает сервис, используя утверждение SAML

Теперь я реализовал сценарий выше в виде трех скриптов LinqPad: client.linq, sts.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. SOAP вызов с действием http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue

    2.2. SOAP вызов с действием http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue

    2,3. Последний SOAP-вызов с действием urn:ihe:iti:2007:CrossGatewayQuery, Используя Fiddler, я заметил, что заголовок безопасности SOAP включает в себя утверждение SAML с первого шага.

Последний вызов приводит к отказу SOAP от службы: не удалось проверить хотя бы один токен безопасности в сообщении. Сохраненный журнал запросов / ответов Fiddler находится здесь: https://drive.google.com/file/d/0B-UZlLvBjjB2S050TXRhVEo2Vmc/view?usp=sharing

Если бы кто-нибудь мог просветить меня относительно следующего, я был бы очень благодарен:

  • Почему клиент WCF отправляет RST/Issue а также RSTS/Issue запросы к /Service (шаги 2.1 и 2.2 выше)?
  • Как я могу настроить части так, чтобы они делали то, что я хочу, то есть отправлять один запрос в STS, а затем один запрос в службу, передавая утверждение SAML, которое я получил от STS.

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, который помог мне понять это.

Другие вопросы по тегам