#wcf #azure #wif #federated-identity #acs
#wcf #azure #с помощью #федеративная идентификация #acs
Вопрос:
Как мне выполнить аутентификацию моего клиента WCF с помощью ACS в моей внутренней службе WCF? Проблема связана с настройкой пользовательской области (которую я не могу понять, как установить).)
Мои ACS настроены аналогично образцам ACS, однако «Область» определяется, как показано ниже.
Выдержка со страницы конфигурации 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
на клиенте?
Комментарии:
1. и вопрос в том ….?
2. @Eugenio — обновлено и уточнено
Ответ №1:
Ваш серверный код выглядит нормально, но 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" );
Комментарии:
1. Спасибо за код! Это стоило 145 баллов репутации.
2. Что нужно было бы сделать, если бы я хотел иметь другое доверие в цепочке? Например, ADFS для ACS в RP? или ACS для преобразования ACS в RP?
3. В этом сценарии вы все еще можете использовать WSTrustChannel для получения токена, за исключением того, что вы использовали бы IssuedTokenWSTrustBinding и указали бы его на конечную точку выпущенного токена ACS (которая является v2 / wstrust/13/issuedtoken-симметричной, v2/ wstrust/13/issuedtoken-асимметричной или v2 / wstrust /13/issuedtoken-bearer, в зависимости от). Затем вы настраиваете свойства IssuerBinding привязки и IssuerAddress привязки, чтобы они указывали на конечную точку вашего сертификата ADFS. Поиск по IssuedTokenWSTrustBinding выдаст множество примеров кода. Как только у вас будет токен из ACS, остальное будет выглядеть так же.
Ответ №2:
Некоторые ответы могут быть лучше поздно, чем никогда. Я не смог найти никакой официальной документации по использованию 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
элемент service client. Для правильной работы она должна быть перемещена в родительский tokenRequestParameters
элемент.
Ответ №3:
На самом деле я не пробовал подход, упомянутый в этой статье MSDN, но из прочтения кажется, что стандартная фабрика каналов не имеет правильных настроек для выполнения того, что вы хотите. WSTrustChannelFactory создан для WIF amp; SAML, но я недостаточно знаком с ACS, чтобы определить, применимо ли это. Эту статью из серии из шести частей, вероятно, тоже стоит прочитать.