Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом примере показано, как реализовать пользовательский токен аутентификации. Аутентификатор токенов в Windows Communication Foundation (WCF) используется для проверки токена, применяемого совместно с сообщением, подтверждения его согласованности и аутентификации идентичности, связанной с токеном.
Аутентификаторы пользовательских токенов полезны в различных ситуациях, например:
Когда вы хотите переопределить механизм проверки подлинности по умолчанию, привязанный к токену.
При создании пользовательского токена.
В этом примере показано следующее:
Как клиент может пройти проверку подлинности с помощью пары имени пользователя и пароля.
Как сервер может проверить учетные данные клиента с помощью пользовательского авторизатора токенов.
Как код службы WCF связан с настроенным токеном аутентификации.
Как сервер может быть аутентифицирован с помощью сертификата X.509 сервера.
В этом примере также показано, как удостоверение вызывающего объекта доступно из WCF после процесса аутентификации пользовательского токена.
Служба предоставляет одну конечную точку для взаимодействия со службой, определенной с помощью файла конфигурации App.config. Конечная точка состоит из адреса, привязки и контракта. Привязка настраивается с помощью стандартного wsHttpBinding с режимом безопасности, установленным как сообщение, — режимом wsHttpBinding по умолчанию. Этот пример задает стандарт wsHttpBinding для использования проверки подлинности имени пользователя клиента. Служба также настраивает сертификат службы, используя поведение serviceCredentials. Поведение securityCredentials позволяет указать сертификат службы. Сертификат службы используется клиентом для проверки подлинности службы и предоставления защиты сообщений. Следующая конфигурация ссылается на сертификат localhost, установленный во время примера установки, как описано в следующих инструкциях по настройке.
<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 address=""
binding="wsHttpBinding"
bindingConfiguration="Binding1"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="False" />
<!--
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>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Конфигурация конечной точки клиента состоит из имени конфигурации, абсолютного адреса конечной точки службы, привязки и контракта. Привязка клиента настроена соответствующими Mode и clientCredentialType.
<system.serviceModel>
<client>
<endpoint name=""
address="http://localhost:8000/servicemodelsamples/service"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
contract="Microsoft.ServiceModel.Samples.ICalculator">
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
Реализация клиента задает имя пользователя и пароль для использования.
static void Main()
{
...
client.ClientCredentials.UserNamePassword.UserName = username;
client.ClientCredentials.UserNamePassword.Password = password;
...
}
Пользовательский токен аутентификатор
Чтобы создать пользовательское средство проверки подлинности токенов, выполните следующие действия.
Напишите настроенный проверяющий токенов.
Пример реализации пользовательского механизма проверки подлинности токенов, который проверяет, соответствует ли имя пользователя допустимому формату электронной почты. Это происходит от UserNameSecurityTokenAuthenticator. Наиболее важным методом этого класса является ValidateUserNamePasswordCore(String, String). В этом методе аутентификатор проверяет формат имени пользователя, а также то, что имя узла не принадлежит к мошенническому домену. Если выполняются оба условия, он возвращает коллекцию IAuthorizationPolicy экземпляров только для чтения, которая затем используется для предоставления утверждений, представляющих сведения, хранящиеся внутри маркера имени пользователя.
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password) { if (!ValidateUserNameFormat(userName)) throw new SecurityTokenValidationException("Incorrect UserName format"); ClaimSet claimSet = new DefaultClaimSet(ClaimSet.System, new Claim(ClaimTypes.Name, userName, Rights.PossessProperty)); List<IIdentity> identities = new List<IIdentity>(1); identities.Add(new GenericIdentity(userName)); List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1); policies.Add(new UnconditionalPolicy(ClaimSet.System, claimSet, DateTime.MaxValue.ToUniversalTime(), identities)); return policies.AsReadOnly(); }Укажите политику авторизации, возвращаемую кастомным маркером аутентификации.
В этом примере представлена собственная реализация IAuthorizationPolicy, называемая
UnconditionalPolicy, которая возвращает набор утверждений и удостоверений, переданных в ее конструктор.class UnconditionalPolicy : IAuthorizationPolicy { String id = Guid.NewGuid().ToString(); ClaimSet issuer; ClaimSet issuance; DateTime expirationTime; IList<IIdentity> identities; public UnconditionalPolicy(ClaimSet issuer, ClaimSet issuance, DateTime expirationTime, IList<IIdentity> identities) { if (issuer == null) throw new ArgumentNullException("issuer"); if (issuance == null) throw new ArgumentNullException("issuance"); this.issuer = issuer; this.issuance = issuance; this.identities = identities; this.expirationTime = expirationTime; } public string Id { get { return this.id; } } public ClaimSet Issuer { get { return this.issuer; } } public DateTime ExpirationTime { get { return this.expirationTime; } } public bool Evaluate(EvaluationContext evaluationContext, ref object state) { evaluationContext.AddToTarget(this, this.issuance); if (this.identities != null) { object value; IList<IIdentity> contextIdentities; if (!evaluationContext.Properties.TryGetValue("Identities", out value)) { contextIdentities = new List<IIdentity>(this.identities.Count); evaluationContext.Properties.Add("Identities", contextIdentities); } else { contextIdentities = value as IList<IIdentity>; } foreach (IIdentity identity in this.identities) { contextIdentities.Add(identity); } } evaluationContext.RecordExpirationTime(this.expirationTime); return true; } }Напишите пользовательский менеджер токенов безопасности.
SecurityTokenManager используется для создания SecurityTokenAuthenticator для конкретных объектов SecurityTokenRequirement, которые передаются в него посредством метода
CreateSecurityTokenAuthenticator. Диспетчер токенов безопасности также используется для создания поставщиков токенов и сериализаторов токенов, но они не рассматриваются в этом примере. В этом примере пользовательский менеджер токенов безопасности наследует от класса ServiceCredentialsSecurityTokenManager и переопределяет методCreateSecurityTokenAuthenticatorдля возврата пользовательского аутентификатора имени пользователя, когда требования к токену показывают, что запрашивается аутентификатор имени пользователя.public class MySecurityTokenManager : ServiceCredentialsSecurityTokenManager { MyUserNameCredential myUserNameCredential; public MySecurityTokenManager(MyUserNameCredential myUserNameCredential) : base(myUserNameCredential) { this.myUserNameCredential = myUserNameCredential; } public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) { if (tokenRequirement.TokenType == SecurityTokenTypes.UserName) { outOfBandTokenResolver = null; return new MyTokenAuthenticator(); } else { return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); } } }Напишите учетные данные специализированной службы.
Класс учетных данных службы используется для представления учетных данных, настроенных для службы, и создает менеджер токенов безопасности, который используется для получения аутентификаторов токенов, провайдеров токенов и сериализаторов токенов.
public class MyUserNameCredential : ServiceCredentials { public MyUserNameCredential() : base() { } protected override ServiceCredentials CloneCore() { return new MyUserNameCredential(); } public override SecurityTokenManager CreateSecurityTokenManager() { return new MySecurityTokenManager(this); } }Настройте службу для использования пользовательского учетного документа службы.
Чтобы служба могла использовать настраиваемые учетные данные, мы удаляем класс учетных данных службы по умолчанию после записи сертификата службы, который уже предварительно настроен в учетных данных по умолчанию. Затем мы настраиваем новый экземпляр учетных данных службы для использования предварительно настроенных сертификатов, добавляя этот новый экземпляр учетных данных в настройки поведения службы.
ServiceCredentials sc = serviceHost.Credentials; X509Certificate2 cert = sc.ServiceCertificate.Certificate; MyUserNameCredential serviceCredential = new MyUserNameCredential(); serviceCredential.ServiceCertificate.Certificate = cert; serviceHost.Description.Behaviors.Remove((typeof(ServiceCredentials))); serviceHost.Description.Behaviors.Add(serviceCredential);
Для отображения сведений вызывающего абонента можно использовать PrimaryIdentity, как показано в следующем коде. Содержит Current сведения о претензиях текущего вызывающего.
static void DisplayIdentityInformation()
{
Console.WriteLine("\t\tSecurity context identity : {0}",
ServiceSecurityContext.Current.PrimaryIdentity.Name);
return;
}
При запуске примера запросы и ответы операции отображаются в окне консоли клиента. Нажмите клавишу ВВОД в окне клиента, чтобы завершить работу клиента.
Настройка пакетного файла
Пакетный файл Setup.bat, включенный в этот пример, позволяет настроить сервер с соответствующими сертификатами для запуска локального приложения, требующего безопасности на основе сертификатов сервера. Для работы этого пакетного файла на разных компьютерах или без хостинга его необходимо изменить.
Ниже приведен краткий обзор различных разделов пакетных файлов, чтобы их можно было изменить для выполнения в соответствующей конфигурации.
Создание сертификата сервера.
Следующие строки из пакетного файла Setup.bat создают используемый сертификат сервера. Переменная
%SERVER_NAME%задает имя сервера. Измените эту переменную, чтобы указать собственное имя сервера. Значение по умолчанию в этом пакетном файле — localhost.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, не являются неявно доверенными клиентской системой. Если у вас уже есть сертификат, основанный на доверенном корневом сертификате клиента, например, выданный корпорацией Майкрософт, этот шаг, в котором хранилище сертификатов клиента заполняется серверным сертификатом, не требуется.
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeopleЗамечание
Пакетный файл программы установки предназначен для запуска из командной строки пакета SDK для Windows. Для этого необходимо, чтобы переменная среды MSSDK указывала на каталог, в котором установлен пакет SDK. Эта переменная среды автоматически устанавливается в командной строке пакета SDK для Windows.
Для настройки и сборки примера
Убедитесь, что вы выполнили процедуру настройки One-Time для образцов Windows Communication Foundation.
Чтобы создать решение, следуйте инструкциям по созданию примеров Windows Communication Foundation.
Запуск примера на том же компьютере
Запустите 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 на компьютер службы.
У вас должен быть сертификат сервера с именем субъекта, который содержит полное доменное имя компьютера. Файл службы App.config необходимо обновить, чтобы отразить это новое имя сертификата. Вы можете создать его с помощью Setup.bat, если для переменной задано
%SERVER_NAME%полное имя узла компьютера, на котором будет выполняться служба. Обратите внимание, что файл setup.bat должен быть запущен из командной строки разработчика для Visual Studio, открытой с правами администратора.Скопируйте сертификат сервера в хранилище CurrentUser-TrustedPeople клиента. Это не нужно делать, за исключением случаев, когда сертификат сервера выдан доверенным издателем клиента.
В файле App.config на компьютере службы измените значение базового адреса, чтобы указать полное имя компьютера вместо localhost.
На компьютере службы запустите service.exe из командной строки.
Скопируйте файлы клиентской программы из папки \client\bin\, зависящей от языка, на клиентский компьютер.
В файле Client.exe.config на клиентском компьютере измените значение адреса конечной точки на соответствие новому адресу службы.
На клиентском компьютере запустите Client.exe из командной строки.
Если клиент и служба не могут взаимодействовать, см. рекомендации по устранению неисправностей для примеров WCF.
Очистка после образца
- Запустите Cleanup.bat в папке примеров после завершения работы примера.