Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом примере показано, как реализовать настраиваемый поставщик токенов SAML клиента. Поставщик токенов в Windows Communication Foundation (WCF) используется для предоставления учетных данных инфраструктуре безопасности. Поставщик токенов в целом проверяет целевой объект и выдает соответствующие учетные данные, чтобы инфраструктура безопасности могли защитить сообщение. WCF поставляется с поставщиком токенов диспетчера учетных данных по умолчанию. WCF также включает в себя провайдера токенов CardSpace. Поставщики пользовательских токенов полезны в следующих случаях:
Если у вас есть хранилище учетных данных, с которыми эти поставщики токенов не могут работать.
Если вы хотите предоставить собственный механизм для преобразования учетных данных, начиная с момента, когда пользователь вводит свои данные, и до их использования в рамках клиентской платформы WCF.
Если вы создаете пользовательский токен.
В этом примере показано, как создать настраиваемого поставщика маркеров, позволяющего использовать токен SAML, полученный за пределами клиентской инфраструктуры WCF.
В этом примере показано следующее:
Как клиент может быть настроен с помощью пользовательского поставщика токенов.
Как токен SAML можно передать пользовательским учетным данным клиента.
Как токен SAML предоставляется клиентской платформе WCF.
Как сервер проходит проверку подлинности клиентом с помощью сертификата X.509 сервера.
Служба предоставляет две конечные точки для взаимодействия со службой, определяемой с помощью файла конфигурации App.config. Каждая конечная точка состоит из адреса, привязки и контракта. Привязка настроена с использованием стандарта wsFederationHttpBinding, использующего безопасность сообщений. Одна конечная точка ожидает, что клиент будет проходить проверку подлинности с помощью токена SAML, использующего симметричный ключ доказательства, а другая ожидает, что клиент будет проходить проверку подлинности с помощью токена SAML, использующего асимметричный ключ доказательства. Служба также настраивает сертификат службы, используя поведение serviceCredentials. Поведение serviceCredentials позволяет настроить сертификат службы. Сертификат службы используется клиентом для проверки подлинности службы и предоставления защиты сообщений. Следующая конфигурация ссылается на сертификат localhost, установленный во время примера установки, как описано в инструкциях по настройке в конце этого раздела. Это serviceCredentials поведение также позволяет настроить сертификаты, которым доверяют для подписания токенов SAML. Следующая конфигурация ссылается на сертификат Alice, установленный во время примера.
<system.serviceModel>
<services>
<service
name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<host>
<baseAddresses>
<!-- configure base address provided by host -->
<add
baseAddress="http://localhost:8000/servicemodelsamples/service/" />
</baseAddresses>
</host>
<!-- use base address provided by host -->
<!-- Endpoint that expect SAML tokens with Symmetric proof keys -->
<endpoint address="calc/symm"
binding="wsFederationHttpBinding"
bindingConfiguration="Binding1"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<!-- Endpoint that expect SAML tokens with Asymmetric proof keys -->
<endpoint address="calc/asymm"
binding="wsFederationHttpBinding"
bindingConfiguration="Binding2"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</service>
</services>
<bindings>
<wsFederationHttpBinding>
<!-- Binding that expect SAML tokens with Symmetric proof keys -->
<binding name="Binding1">
<security mode="Message">
<message negotiateServiceCredential ="false"
issuedKeyType="SymmetricKey"
issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" />
</security>
</binding>
<!-- Binding that expect SAML tokens with Asymmetric proof keys -->
<binding name="Binding2">
<security mode="Message">
<message negotiateServiceCredential ="false"
issuedKeyType="AsymmetricKey"
issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" />
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by a client to authenticate the service and provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCredentials>
<!-- Set allowUntrustedRsaIssuers to true to allow self-signed, asymmetric key based SAML tokens -->
<issuedTokenAuthentication allowUntrustedRsaIssuers ="true" >
<!-- Add Alice to the list of certs trusted to issue SAML tokens -->
<knownCertificates>
<add storeLocation="LocalMachine"
storeName="TrustedPeople"
x509FindType="FindBySubjectName"
findValue="Alice"/>
</knownCertificates>
</issuedTokenAuthentication>
<serviceCertificate storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"
findValue="localhost" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Ниже показано, как разработать пользовательский поставщик токенов SAML и интегрировать его с инфраструктурой безопасности WCF.
Напишите собственный поставщик токенов SAML.
В примере реализуется настраиваемый поставщик токенов SAML, который возвращает токен безопасности на основе утверждения SAML, предоставленного во время создания.
Для выполнения этой задачи поставщик настраиваемых маркеров является производным от SecurityTokenProvider класса и переопределяет GetTokenCore метод. Этот метод создает и возвращает новое
SecurityToken.protected override SecurityToken GetTokenCore(TimeSpan timeout) { // Create a SamlSecurityToken from the provided assertion SamlSecurityToken samlToken = new SamlSecurityToken(assertion); // Create a SecurityTokenSerializer that will be used to // serialize the SamlSecurityToken WSSecurityTokenSerializer ser = new WSSecurityTokenSerializer(); // Create a memory stream to write the serialized token into // Use an initial size of 64Kb MemoryStream s = new MemoryStream(UInt16.MaxValue); // Create an XmlWriter over the stream XmlWriter xw = XmlWriter.Create(s); // Write the SamlSecurityToken into the stream ser.WriteToken(xw, samlToken); // Seek back to the beginning of the stream s.Seek(0, SeekOrigin.Begin); // Load the serialized token into a DOM XmlDocument dom = new XmlDocument(); dom.Load(s); // Create a KeyIdentifierClause for the SamlSecurityToken SamlAssertionKeyIdentifierClause samlKeyIdentifierClause = samlToken.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>(); // Return a GenericXmlToken from the XML for the // SamlSecurityToken, the proof token, the valid from and valid // until times from the assertion and the key identifier clause // created above return new GenericXmlSecurityToken(dom.DocumentElement, proofToken, assertion.Conditions.NotBefore, assertion.Conditions.NotOnOrAfter, samlKeyIdentifierClause, samlKeyIdentifierClause, null); }Напишите пользовательский менеджер токенов безопасности.
Класс SecurityTokenManager используется для создания SecurityTokenProvider определенного SecurityTokenRequirement объекта, передаваемого в него в
CreateSecurityTokenProviderметоде. Диспетчер маркеров безопасности также используется для создания аутентификаторов и сериализаторов маркеров, однако эти функции не охватываются данным примером. В этом примере специализированный менеджер маркеров безопасности наследует от ClientCredentialsSecurityTokenManager класса и переопределяетCreateSecurityTokenProviderметод, чтобы возвращать пользовательского поставщика токенов SAML, когда требования к токенам указывают, что запрашивается маркер SAML. Если класс учетных данных клиента (см. шаг 3) не установил утверждение, менеджер токенов безопасности создает соответствующий экземпляр.public class SamlSecurityTokenManager : ClientCredentialsSecurityTokenManager { SamlClientCredentials samlClientCredentials; public SamlSecurityTokenManager ( SamlClientCredentials samlClientCredentials) : base(samlClientCredentials) { // Store the creating client credentials this.samlClientCredentials = samlClientCredentials; } public override SecurityTokenProvider CreateSecurityTokenProvider ( SecurityTokenRequirement tokenRequirement ) { // If token requirement matches SAML token return the // custom SAML token provider if (tokenRequirement.TokenType == SecurityTokenTypes.Saml || tokenRequirement.TokenType == "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1") { // Retrieve the SAML assertion and proof token from the // client credentials SamlAssertion assertion = this.samlClientCredentials.Assertion; SecurityToken prooftoken = this.samlClientCredentials.ProofToken; // If either the assertion of proof token is null... if (assertion == null || prooftoken == null) { // ...get the SecurityBindingElement and then the // specified algorithm suite SecurityBindingElement sbe = null; SecurityAlgorithmSuite sas = null; if ( tokenRequirement.TryGetProperty<SecurityBindingElement> ( "http://schemas.microsoft.com/ws/2006/05/servicemodel/securitytokenrequirement/SecurityBindingElement", out sbe)) { sas = sbe.DefaultAlgorithmSuite; } // If the token requirement is for a SymmetricKey based token.. if (tokenRequirement.KeyType == SecurityKeyType.SymmetricKey) { // Create a symmetric proof token prooftoken = SamlUtilities.CreateSymmetricProofToken ( tokenRequirement.KeySize ); // and a corresponding assertion based on the claims specified in the client credentials assertion = SamlUtilities.CreateSymmetricKeyBasedAssertion ( this.samlClientCredentials.Claims, new X509SecurityToken ( samlClientCredentials.ClientCertificate.Certificate ), new X509SecurityToken ( samlClientCredentials.ServiceCertificate.DefaultCertificate ), (BinarySecretSecurityToken)prooftoken, sas); } // otherwise... else { // Create an asymmetric proof token prooftoken = SamlUtilities.CreateAsymmetricProofToken(); // and a corresponding assertion based on the claims // specified in the client credentials assertion = SamlUtilities.CreateAsymmetricKeyBasedAssertion ( this.samlClientCredentials.Claims, prooftoken, sas ); } } // Create a SamlSecurityTokenProvider based on the assertion and proof token return new SamlSecurityTokenProvider(assertion, prooftoken); } // otherwise use base implementation else { return base.CreateSecurityTokenProvider(tokenRequirement); } }Напишите пользовательские учетные данные клиента.
Класс учетных данных клиента используется для представления учетных данных, настроенных для клиентского прокси-сервера, и создает менеджер токенов безопасности, используемый для получения аутентификационных токенов, поставщиков токенов и сериализатора токенов.
public class SamlClientCredentials : ClientCredentials { ClaimSet claims; SamlAssertion assertion; SecurityToken proofToken; public SamlClientCredentials() : base() { // Set SupportInteractive to false to suppress Cardspace UI base.SupportInteractive = false; } protected SamlClientCredentials(SamlClientCredentials other) : base ( other ) { // Just do reference copy given sample nature this.assertion = other.assertion; this.claims = other.claims; this.proofToken = other.proofToken; } public SamlAssertion Assertion { get { return assertion; } set { assertion = value; } } public SecurityToken ProofToken { get { return proofToken; } set { proofToken = value; } } public ClaimSet Claims { get { return claims; } set { claims = value; } } protected override ClientCredentials CloneCore() { return new SamlClientCredentials(this); } public override SecurityTokenManager CreateSecurityTokenManager() { // return custom security token manager return new SamlSecurityTokenManager(this); } }Настройте клиент для использования пользовательских учетных данных клиента.
Пример удаляет класс учетных данных клиента по умолчанию и предоставляет новый класс учетных данных клиента, чтобы клиент смог использовать пользовательские учетные данные клиента.
// Create new credentials class SamlClientCredentials samlCC = new SamlClientCredentials(); // Set the client certificate. This is the cert that will be used to sign the SAML token in the symmetric proof key case samlCC.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "Alice"); // Set the service certificate. This is the cert that will be used to encrypt the proof key in the symmetric proof key case samlCC.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.TrustedPeople, X509FindType.FindBySubjectName, "localhost"); // Create some claims to put in the SAML assertion IList<Claim> claims = new List<Claim>(); claims.Add(Claim.CreateNameClaim(samlCC.ClientCertificate.Certificate.Subject)); ClaimSet claimset = new DefaultClaimSet(claims); samlCC.Claims = claimset; // set new credentials client.ChannelFactory.Endpoint.Behaviors.Remove(typeof(ClientCredentials)); client.ChannelFactory.Endpoint.Behaviors.Add(samlCC);
В службе отображаются утверждения, связанные с вызывающим оператором. При запуске примера запросы и ответы операции отображаются в окне консоли клиента. Нажмите клавишу ВВОД в окне клиента, чтобы завершить работу клиента.
Настройка пакетного файла
Пакетный файл Setup.bat, включенный в этот пример, позволяет настроить сервер с соответствующим сертификатом для запуска локального приложения, требующего безопасности на основе сертификатов сервера. Для работы этого пакетного файла на разных компьютерах или без хостинга его необходимо изменить.
Ниже представлены общие сведения о различных разделах пакетных файлов, позволяющие изменять их для выполнения в соответствующей конфигурации.
Создание сертификата сервера:
Следующие строки из пакетного файла Setup.bat создают используемый сертификат сервера. Переменная
%SERVER_NAME%задает имя сервера. Измените эту переменную, чтобы указать собственное имя сервера. Значение по умолчанию в этом пакетном файле — localhost.Сертификат хранится в хранилище «My store (Личном хранилище)» в расположении LocalMachine.
echo ************ echo Server cert setup starting echo %SERVER_NAME% echo ************ echo making server cert echo ************ makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=%SERVER_NAME% -sky exchange -peУстановка сертификата сервера в доверенное хранилище сертификатов клиента:
Следующие строки в пакетном файле Setup.bat копируют сертификат сервера в хранилище доверенных пользователей клиента. Этот шаг необходим, так как сертификаты, созданные Makecert.exe, не являются неявно доверенными клиентской системой. Если у вас уже есть сертификат, который основывается на корневом сертификате, которому доверяет клиент, например, выданный корпорацией Microsoft, то этап добавления серверного сертификата в хранилище клиентских сертификатов не требуется.
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r LocalMachine -s TrustedPeopleСоздание сертификата издателя.
Следующие строки из пакетного файла Setup.bat создают сертификат издателя, который будет использоваться. Переменная
%USER_NAME%задает имя издателя. Измените эту переменную, чтобы указать собственное имя издателя. Значением по умолчанию в этом пакетном файле является Алиса.Сертификат хранится в хранилище "Мое" в расположении хранилища "CurrentUser".
echo ************ echo Server cert setup starting echo %SERVER_NAME% echo ************ echo making server cert echo ************ makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=%USER_NAME% -sky exchange -peУстановка сертификата издателя в доверенное хранилище сертификатов сервера.
Следующие строки в пакетном файле Setup.bat копируют сертификат сервера в хранилище доверенных пользователей клиента. Этот шаг необходим, так как сертификаты, созданные Makecert.exe, не являются неявно доверенными клиентской системой. Если у вас уже есть сертификат, корневой сертификат которого доверен клиентом, например, выданный корпорацией Майкрософт, то этот шаг по заполнению хранилища сертификатов сервера сертификатом издателя не требуется.
certmgr.exe -add -r CurrentUser -s My -c -n %USER_NAME% -r LocalMachine -s TrustedPeople
Для настройки и сборки примера
Убедитесь, что вы выполнили процедуру настройки One-Time для образцов Windows Communication Foundation.
Чтобы создать решение, следуйте инструкциям по созданию примеров Windows Communication Foundation.
Замечание
Если вы используете Svcutil.exe для повторного создания конфигурации для этого примера, обязательно измените имя конечной точки в конфигурации клиента, чтобы соответствовать коду клиента.
Запуск примера на том же компьютере
Запустите Setup.bat из папки примера установки в командной строке Visual Studio, запущенной с правами администратора. При этом устанавливаются все сертификаты, необходимые для выполнения примера.
Замечание
Пакетный файл Setup.bat предназначен для запуска из командной строки Visual Studio. Переменная среды PATH в командной строке Visual Studio указывает на каталог, содержащий исполняемые файлы, необходимые скрипту Setup.bat.
Запустите Service.exe из service\bin.
Запустите Client.exe из \client\bin. Действие клиента отображается в клиентском консольном приложении.
Если клиент и служба не могут взаимодействовать, см. рекомендации по устранению неисправностей для примеров WCF.
Для запуска примера на нескольких компьютерах
Создайте каталог на компьютере сервиса для файлов двоичного кода сервиса.
Скопируйте файлы программы службы в каталог службы на компьютере службы. Кроме того, скопируйте файлы Setup.bat и Cleanup.bat на компьютер службы.
У вас должен быть сертификат сервера с именем субъекта, который содержит полное доменное имя компьютера. Файл Service.exe.config необходимо обновить, чтобы отразить это новое имя сертификата. Вы можете создать сертификат сервера, изменив Setup.bat пакетный файл. Обратите внимание, что файл setup.bat должен быть запущен в командной строке разработчика для Visual Studio, открываемом с правами администратора. Необходимо задать переменной
%SERVER_NAME%полное имя узла компьютера, который используется для размещения службы.Скопируйте сертификат сервера в хранилище CurrentUser-TrustedPeople клиента. Этот шаг не требуется, если сертификат сервера выдан доверенным издателем клиента.
В файле Service.exe.config на компьютере службы измените значение базового адреса, чтобы указать полное имя компьютера вместо localhost.
На компьютере службы запустите Service.exe из командной строки.
Скопируйте файлы клиентской программы из папки \client\bin\ в папку, соответствующую конкретному языку, на клиентский компьютер.
В файле Client.exe.config на клиентском компьютере измените значение адреса конечной точки на соответствие новому адресу службы.
На клиентском компьютере запустите
Client.exeиз окна командной строки.Если клиент и служба не могут взаимодействовать, см. рекомендации по устранению неисправностей для примеров WCF.
Очистка после образца
- Запустите Cleanup.bat в папке примеров после завершения работы примера.