Как настроить WCF для использования пользовательской области в формате URN с Azure ACS?

Как заставить мой клиент WCF аутентифицироваться с помощью ACS в моей внутренней службе WCF? Проблема связана с настройкой пользовательского Царства (которое я не могу понять, как установить).

Мой ACS настроен аналогично примерам ACS, однако " Realm» определяется, как показано ниже.

Выдержка со страницы конфигурации Azure ACS


определение области


Клиентский код

      EndpointAddress serviceEndpointAddress = new EndpointAddress( new Uri( "http://localhost:7000/Service/Default.aspx"),  
                                                                      EndpointIdentity.CreateDnsIdentity( GetServiceCertificateSubjectName() ),
                                                                      new AddressHeaderCollection() );

        ChannelFactory<IStringService> stringServiceFactory = new ChannelFactory<IStringService>(Bindings.CreateServiceBinding("https://agent7.accesscontrol.appfabriclabs.com/v2/wstrust/13/certificate"), serviceEndpointAddress );

        // Set the service credentials.
        stringServiceFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
        stringServiceFactory.Credentials.ServiceCertificate.DefaultCertificate = GetServiceCertificate();

        // Set the client credentials.
        stringServiceFactory.Credentials.ClientCertificate.Certificate = GetClientCertificateWithPrivateKey();

Код на стороне сервера

 string acsCertificateEndpoint = String.Format( "https://{0}.{1}/v2/wstrust/13/certificate", AccessControlNamespace, AccessControlHostName );

        ServiceHost rpHost = new ServiceHost( typeof( StringService ) );

        rpHost.Credentials.ServiceCertificate.Certificate = GetServiceCertificateWithPrivateKey();

        rpHost.AddServiceEndpoint( typeof( IStringService ),
                                   Bindings.CreateServiceBinding( acsCertificateEndpoint ),
                                   "http://localhost:7000/Service/Default.aspx"
                                   );

        //
        // This must be called after all WCF settings are set on the service host so the
        // Windows Identity Foundation token handlers can pick up the relevant settings.
        //
        ServiceConfiguration serviceConfiguration = new ServiceConfiguration();
        serviceConfiguration.CertificateValidationMode = X509CertificateValidationMode.None;

        // Accept ACS signing certificate as Issuer.
        serviceConfiguration.IssuerNameRegistry = new X509IssuerNameRegistry( GetAcsSigningCertificate().SubjectName.Name );

        // Add the SAML 2.0 token handler.
        serviceConfiguration.SecurityTokenHandlers.AddOrReplace( new Saml2SecurityTokenHandler() );

        // Add the address of this service to the allowed audiences.
        serviceConfiguration.SecurityTokenHandlers.Configuration.AudienceRestriction.AllowedAudienceUris.Add( new Uri( "urn:federation:customer:222:agent:11") );

        FederatedServiceCredentials.ConfigureServiceHost( rpHost, serviceConfiguration );

        return rpHost;

... где urn:federation:customer:222:agent:11 — идентификатор проверяющей стороны

... и http://localhost:7000/Service/Default.aspx - это место, к которому я хочу привязать вышеуказанный клиент WCF/WIF после выполнения аутентификации ACS.

Вопрос

Как отредактировать приведенный выше код, чтобы клиент и сервер работали с определенным портом (localhost:700), а также с областью urn:federation:customer:222:agent:11

Я думаю, что у меня правильный код сервера; однако как мне установить AudienceRestriction на клиенте?


person halfbit    schedule 08.04.2011    source источник
comment
а вопрос....?   -  person Eugenio Pace    schedule 09.04.2011
comment
@Eugenio - обновлено и уточнено   -  person halfbit    schedule 09.04.2011


Ответы (3)


Ваш серверный код выглядит нормально, но Sixto прав насчет стандартных фабрик каналов. К счастью, вы можете самостоятельно запросить токен безопасности у ACS, используя WSTrustChannelFactory. В контексте вашего примера ваш код будет выглядеть так:

//
// Get the token from ACS
//
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(
    Bindings.CreateAcsCertificateBinding(),
    new EndpointAddress( acsCertificateEndpoint ) );
trustChannelFactory.Credentials.ClientCertificate.Certificate = GetClientCertificateWithPrivateKey();

RequestSecurityToken rst = new RequestSecurityToken()
{
    RequestType = RequestTypes.Issue,
    AppliesTo = new EndpointAddress( new Uri( "urn:federation:customer:222:agent:11" ) ),
    KeyType = KeyTypes.Symmetric
};

WSTrustChannel wsTrustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel();
SecurityToken token = wsTrustChannel.Issue( rst );

//
// Call StringService, authenticating with the retrieved token
//
WS2007FederationHttpBinding binding = new WS2007FederationHttpBinding( WSFederationHttpSecurityMode.Message );
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.NegotiateServiceCredential = false;

ChannelFactory<IStringService> factory = new ChannelFactory<IStringService>(
    binding,
    new EndpointAddress(
            new Uri( ServiceAddress ),
            EndpointIdentity.CreateDnsIdentity(GetServiceCertificateSubjectName()) ) );
factory.ConfigureChannelFactory<IStringService>();
factory.Credentials.SupportInteractive = false;
factory.Credentials.ServiceCertificate.DefaultCertificate = GetServiceCertificate();

IStringService channel = factory.CreateChannelWithIssuedToken<IStringService>( token );
string reversedString = channel.Reverse( "string to reverse" );
person Andrew Lavers    schedule 13.04.2011
comment
Спасибо за код! Это стоило +145 очков повторения. - person halfbit; 13.04.2011
comment
Что нужно будет сделать, если я захочу получить еще один траст в сети? Например, ADFS в ACS в RP? или АСУ к АСУ к РП? - person halfbit; 14.04.2011
comment
В этом сценарии вы по-прежнему можете использовать WSTrustChannel для получения токена, за исключением того, что вы будете использовать IssuedTokenWSTrustBinding и указать его на конечную точку выданного токена ACS (которая является v2/wstrust/13/issuedtoken-симметричным, v2/wstrust/ 13/issuedtoken-aсимметричный или v2/wstrust/13/issuedtoken-bearer, в зависимости от). Затем вы настраиваете свойства IssuerBinding и IssuerAddress привязки, чтобы они указывали на конечную точку сертификата ADFS. Поиск IssuedTokenWSTrustBinding даст множество примеров кода. Если у вас есть токен от ACS, все остальное выглядит так же. - person Andrew Lavers; 16.04.2011

Некоторые ответы могут быть лучше поздно, чем никогда. Мне не удалось найти какую-либо официальную документацию по использованию WCF таким образом, однако, прочитав документы WS-Trust и документацию MSDN по настройке, я пришел к следующему решению, которое, похоже, работает.

Из службы, использующей конфигурацию клиента по адресу configuration/system.serviceModel/bindings/ws2007FederationHttpbinding/binding/security/message. Он переопределяет элемент AppliesTo сообщения запроса токена.

<tokenRequestParameters>
  <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
    <EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
      <Address>urn:x-Organization:Testing</Address>
    </EndpointReference>
  </wsp:AppliesTo>
</tokenRequestParameters>

Добавление этого фрагмента в конфигурацию службы приведет к тому, что утилита Service Reference включит его в элемент trust:SecondaryParameters клиента службы. Для корректной работы его необходимо переместить в родительский элемент tokenRequestParameters.

person psaxton    schedule 19.06.2013

На самом деле не пробовал подход, упомянутый в этой статье MSDN, но прочитав похоже, что у стандартной фабрики каналов нет нужных крючков, чтобы делать то, что вы хотите. WSTrustChannelFactory создан для WIF и SAML, но я недостаточно знаком с ACS, чтобы определить, применимо ли это. Эту статью из этой серии из шести частей, вероятно, тоже стоит прочитать.

person Sixto Saez    schedule 12.04.2011