Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В примере TrustedFacade демонстрируется передача информации об идентификации вызывающего объекта из одной службы в другую посредством инфраструктуры безопасности Windows Communication Foundation (WCF).
Это распространенный шаблон проектирования для того, чтобы с помощью службы-фасада предоставлять в публичную сеть функциональные возможности, предлагаемые службой. Служба фасадов обычно находится в сети периметра (также известной как DMZ, демилитаризованная зона и экранированная подсеть) и взаимодействует с серверной службой, которая реализует бизнес-логику и имеет доступ к внутренним данным. Канал связи между службой фасада и серверной службой проходит через брандмауэр и обычно ограничен только для одной цели.
Этот пример состоит из следующих компонентов:
Клиент калькулятора
Служба интерфейса калькулятора
Серверная служба калькулятора
Фасадный сервис отвечает за проверку запроса и аутентификацию вызывающего абонента. После успешной проверки подлинности и проверки он перенаправляет запрос в серверную службу с помощью управляемого канала связи из сети периметра во внутреннюю сеть. В рамках пересылаемого запроса интерфейсная служба включает информацию об идентичности вызывающего, чтобы бэкэнд-сервис мог использовать эту информацию в своей работе. Идентификатор вызывающего передается с использованием Username маркера безопасности в заголовке сообщения Security. В примере используется инфраструктура безопасности WCF для передачи и извлечения этих сведений из заголовка Security .
Это важно
Бэкэнд-сервис доверяет фасадной службе аутентификацию вызывающего. Из-за этого сервер снова не проводит аутентификацию вызывающего; он использует данные об идентификации, предоставленные фасадной службой в переадресованном запросе. Из-за этой доверительной связи серверная служба должна удостоверить подлинность службы фасада, чтобы убедиться, что пересылаемое сообщение поступает из надежного источника — в данном случае, службы фасада.
Внедрение
В этом примере есть два пути связи. Первый — между клиентом и службой фасада, а второй — между службой фасада и серверной службой.
Путь взаимодействия между клиентом и службой фасадов
Клиент в пути связи с фасадной службой использует wsHttpBinding с типом учетных данных клиента UserName. Это означает, что клиент использует имя пользователя и пароль для проверки подлинности в службе фасада, а служба фасада использует сертификат X.509 для проверки подлинности клиента. Конфигурация привязки выглядит следующим образом.
<bindings>
<wsHttpBinding>
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
Служба интерфейса проверяет подлинность вызывающего объекта с помощью пользовательской UserNamePasswordValidator реализации. В демонстрационных целях проверка подлинности гарантирует, что имя пользователя совпадает с представленным паролем. В реальной ситуации пользователь, вероятно, проходит проверку подлинности с помощью Active Directory или пользовательского поставщика членства ASP.NET. Реализация валидатора находится в FacadeService.cs файле.
public class MyUserNamePasswordValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
// check that username matches password
if (null == userName || userName != password)
{
Console.WriteLine("Invalid username or password");
throw new SecurityTokenValidationException(
"Invalid username or password");
}
}
}
Настраиваемый валидатор настроен для использования внутри serviceCredentials поведения в файле конфигурации фасадной службы. Это поведение также используется для настройки сертификата X.509 службы.
<behaviors>
<serviceBehaviors>
<behavior name="FacadeServiceBehavior">
<!--The serviceCredentials behavior allows you to define -->
<!--a service certificate. -->
<!--A service certificate is used by the service to -->
<!--authenticate itself to its clients and to provide -->
<!--message protection. -->
<!--This configuration references the "localhost" -->
<!--certificate installed during the setup instructions. -->
<serviceCredentials>
<serviceCertificate
findValue="localhost"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType=
"Microsoft.ServiceModel.Samples.MyUserNamePasswordValidator,
FacadeService"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Путь связи между сервисом фасада и бэкенд-сервисом
Служба фасада для пути обмена данными серверной службы использует элемент customBinding , состоящий из нескольких элементов привязки. Эта привязка выполняет две задачи. Происходит аутентификация фасадного сервиса и серверного сервиса для обеспечения безопасности связи и подтверждения, что она поступает из надежного источника. Кроме того, он передает идентичность исходного вызывающего абонента внутри токена безопасности. В этом случае только имя пользователя инициатора вызова передается в серверную часть, при этом пароль не включен в сообщение. Это связано с тем, что серверная служба доверяет фасадной службе аутентификацию вызывающего перед пересылкой ему запроса. Так как служба фасада проходит проверку подлинности в серверной службе, серверная служба может доверять сведениям, содержащимся в переадресованном запросе.
Ниже приведена конфигурация привязки для этого пути связи.
<bindings>
<customBinding>
<binding name="ClientBinding">
<security authenticationMode="UserNameOverTransport"/>
<windowsStreamSecurity/>
<tcpTransport/>
</binding>
</customBinding>
</bindings>
Компонент <привязки безопасности> отвечает за передачу и извлечение имени пользователя первоначального вызывающего. <windowsStreamSecurity> и <tcpTransport> заботятся о проверке подлинности фасадных и внутренних служб и защите сообщений.
Чтобы переадресовать запрос, реализация службы фасада должна предоставить имя пользователя исходного абонента, чтобы инфраструктура безопасности WCF разместила его в переадресованном сообщении. Имя пользователя первоначального вызывающего предоставляется в реализации службы фасада, поместив его в свойство ClientCredentials в экземпляре клиентского прокси, который служба фасада использует для связи с задним сервисом.
В следующем коде показано, как метод GetCallerIdentity реализуется в службе фасада. Другие методы используют тот же шаблон.
public string GetCallerIdentity()
{
CalculatorClient client = new CalculatorClient();
client.ClientCredentials.UserName.UserName = ServiceSecurityContext.Current.PrimaryIdentity.Name;
string result = client.GetCallerIdentity();
client.Close();
return result;
}
Как показано в предыдущем коде, пароль не задан в ClientCredentials свойстве, задано только имя пользователя. Инфраструктура безопасности WCF создает маркер безопасности имени пользователя без пароля в этом случае, что именно необходимо в этом сценарии.
В серверной службе сведения, содержащиеся в маркере безопасности имени пользователя, должны пройти проверку подлинности. По умолчанию безопасность WCF пытается сопоставить пользователя с учетной записью Windows с помощью предоставленного пароля. В этом случае пароль отсутствует, и серверной службе не требуется проверять подлинность имени пользователя, так как проверка подлинности уже была выполнена службой фасада. Для реализации этой функции в WCF предоставляется настраиваемый элемент UserNamePasswordValidator, который гарантирует, что имя пользователя указано в токене и не выполняет дополнительных проверок подлинности.
public class MyUserNamePasswordValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
// Ignore the password because it is empty,
// we trust the facade service to authenticate the client.
// Accept the username information here so that the
// application gets access to it.
if (null == userName)
{
Console.WriteLine("Invalid username");
throw new
SecurityTokenValidationException("Invalid username");
}
}
}
Настраиваемый валидатор настроен для использования внутри serviceCredentials поведения в файле конфигурации фасадной службы.
<behaviors>
<serviceBehaviors>
<behavior name="BackendServiceBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType=
"Microsoft.ServiceModel.Samples.MyUserNamePasswordValidator,
BackendService"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Чтобы извлечь сведения о имени пользователя и сведения о доверенной учетной записи службы фасада, реализация серверной службы использует ServiceSecurityContext класс. В следующем коде показано, как метод GetCallerIdentity реализуется.
public string GetCallerIdentity()
{
// Facade service is authenticated using Windows authentication.
//Its identity is accessible.
// On ServiceSecurityContext.Current.WindowsIdentity.
string facadeServiceIdentityName =
ServiceSecurityContext.Current.WindowsIdentity.Name;
// The client name is transmitted using Username authentication on
//the message level without the password
// using a supporting encrypted UserNameToken.
// Claims extracted from this supporting token are available in
// ServiceSecurityContext.Current.AuthorizationContext.ClaimSets
// collection.
string clientName = null;
foreach (ClaimSet claimSet in
ServiceSecurityContext.Current.AuthorizationContext.ClaimSets)
{
foreach (Claim claim in claimSet)
{
if (claim.ClaimType == ClaimTypes.Name &&
claim.Right == Rights.Identity)
{
clientName = (string)claim.Resource;
break;
}
}
}
if (clientName == null)
{
// In case there was no UserNameToken attached to the request.
// In the real world implementation the service should reject
// this request.
return "Anonymous caller via " + facadeServiceIdentityName;
}
return clientName + " via " + facadeServiceIdentityName;
}
Сведения об учетной записи службы фасада извлекаются свойством ServiceSecurityContext.Current.WindowsIdentity. Для доступа к сведениям об исходном вызывающем абоненте серверная служба использует ServiceSecurityContext.Current.AuthorizationContext.ClaimSets свойство. Он ищет Identity утверждение с типом Name. Это утверждение автоматически создается системой безопасности WCF из информации, содержащейся в маркере безопасности Username.
Запуск примера
При запуске примера запросы и ответы операции отображаются в окне консоли клиента. Нажмите клавишу ВВОД в окне клиента, чтобы завершить работу клиента. Чтобы завершить работу служб, можно нажать клавишу ВВОД в окнах фасадной и серверной консоли службы.
Username authentication required.
Provide a valid machine or domain ac
Enter username:
user
Enter password:
****
user via MyMachine\testaccount
Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Press <ENTER> to terminate client.
Пакетный файл Setup.bat, включенный в пример сценария доверенного фасада, позволяет настроить сервер с соответствующим сертификатом для запуска службы фасада, требующей безопасности на основе сертификатов для проверки подлинности самого клиента. Дополнительные сведения см. в процедуре установки в конце этого раздела.
Ниже приведен краткий обзор различных разделов пакетных файлов.
Создание сертификата сервера.
Следующие строки из пакетного файла Setup.bat создают используемый сертификат сервера.
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Переменная
%SERVER_NAME%задает имя сервера — значение по умолчанию — localhost. Сертификат хранится в хранилище LocalMachine.Установка сертификата службы фасада в доверенное хранилище сертификатов клиента.
В следующей строке сертификат службы фасада копируется в хранилище доверенных пользователей клиента. Этот шаг необходим, так как сертификаты, созданные Makecert.exe, не являются неявно доверенными клиентской системой. Если у вас уже есть сертификат, который основывается на корневом сертификате, которому доверяет клиент, например, выданный корпорацией Microsoft, то этап добавления серверного сертификата в хранилище клиентских сертификатов не требуется.
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
Настройка, сборка и запуск примера
Убедитесь, что вы выполнили процедуру настройки One-Time для образцов Windows Communication Foundation.
Чтобы создать версию решения на C# или Visual Basic .NET, следуйте инструкциям по сборке примеров Windows Communication Foundation .
Запуск примера на том же компьютере
Убедитесь, что путь содержит папку, в которой находится Makecert.exe.
Запустите Setup.bat из папки установки примера. При этом устанавливаются все сертификаты, необходимые для выполнения примера.
Запустите BackendService.exe из каталога \BackendService\bin в отдельном окне консоли
Запустите FacadeService.exe из каталога \FacadeService\bin в отдельном окне консоли
Запустите Client.exe из \client\bin. Действие клиента отображается в клиентском консольном приложении.
Если клиент и служба не могут взаимодействовать, см. рекомендации по устранению неисправностей для примеров WCF.
Очистка после образца
- Запустите Cleanup.bat в папке примеров после завершения работы примера.