Как создать маркер контекста безопасности с отслеживанием состояния для безопасного сеанса
При использовании в безопасном сеансе маркера контекста безопасности (SCT) с отслеживанием состояния сеанс может сохраняться и при перезапуске службы. Например, если в безопасном сеансе используется маркер SCT без отслеживания состояния, то при сбросе служб IIS данные сеанса, связанного со службой, будут потеряны. В состав данных сеанса входит кэш маркера SCT. Поэтому в следующий раз, когда клиент отправляет в службу маркер SCT без отслеживания состояния, возвращается ошибка, так как невозможно извлечь ключ, связанный с этим маркером SCT. Однако если используется маркер SCT с отслеживанием состояния, то ключ, связанный с маркером SCT, содержится в этом маркере SCT. Так как ключ содержится в маркере SCT и, следовательно, в сообщении, перезапуск службы не влияет на безопасный сеанс. По умолчанию для безопасных сеансов в Windows Communication Foundation (WCF) используются маркеры SCT без отслеживания состояния. В этом разделе описывается, как использовать в безопасном сеансе маркеры SCT с отслеживанием состояния.
Примечание |
---|
Маркеры SCT с отслеживанием состояния не могут использоваться в безопасном сеансе, связанном с контрактом, унаследованным от IDuplexChannel. |
Примечание |
---|
Для приложений, использующих в безопасных сеансах маркеры SCT с отслеживанием состояния, идентификатором потока для службы должна быть учетная запись пользователя, имеющая связанный с ней профиль пользователя. Если служба запущена с учетной записью, не имеющей профиля пользователя (например, Local Service), возможно возникновение исключения. |
Примечание |
---|
Если в ОС Windows XP требуется олицетворение, следует использовать безопасный сеанс без маркера SCT с отслеживанием состояния. При использовании маркеров SCT с отслеживанием состояния вместе с олицетворением возникает исключение InvalidOperationException. Дополнительные сведения см. в разделе Неподдерживаемые сценарии. |
Создайте пользовательскую привязку, которая задает, что сообщения SOAP защищаются безопасным сеансом, использующим маркер SCT с отслеживанием состояния.
Определите пользовательскую привязку, добавив customBinding Element в файл конфигурации службы.
<customBinding>
Добавьте дочерний элемент <binding> в элемент customBinding Element.
Укажите имя привязки, задав для атрибута name имя, уникальное в пределах этого файла конфигурации.
<binding name="StatefulSCTSecureSession">
Укажите режим проверки подлинности для сообщений, отправляемых в эту службу и из нее, добавив дочерний элемент security element of customBinding в элемент customBinding Element.
Укажите, что используется безопасный сеанс, задав для атрибута authenticationMode значение SecureConversation. Укажите, что используются маркеры SCT с отслеживанием состояния, задав для атрибута requireSecurityContextCancellation значение false.
<security authenticationMode="SecureConversation" requireSecurityContextCancellation="false">
Укажите, как производится проверка подлинности клиента во время установления безопасного сеанса, добавив дочерний элемент secureConversationBootstrap element в элемент security element of customBinding.
Укажите, как производится проверка подлинности клиента, задав атрибут authenticationMode.
<secureConversationBootstrap authenticationMode="UserNameForCertificate" />
Укажите кодировку сообщения, добавив элемент кодирования, такой как textMessageEncoding element.
<textMessageEncoding />
Укажите транспорт, добавив транспортный элемент, такой как httpTransport element.
<httpTransport />
В следующем примере кода с помощью конфигурации задается пользовательская привязка, которая может использоваться сообщениями с маркерами SCT с отслеживанием состояния в безопасном сеансе.
<customBinding> <binding name="StatefulSCTSecureSession"> <security authenticationMode="SecureConversation" requireSecurityContextCancellation="false"> <secureConversationBootstrap authenticationMode="UserNameForCertificate" /> </security> <textMessageEncoding /> <httpTransport /> </binding> </customBinding>
В следующем примере кода создается пользовательская привязка, которая использует режим проверки подлинности MutualCertificate для начальной загрузки безопасного сеанса.
Dim security As SecurityBindingElement = SecurityBindingElement.CreateMutualCertificateBindingElement()
' Use a secure session and specify that stateful SecurityContextToken security tokens are used.
security = SecurityBindingElement.CreateSecureConversationBindingElement(security, False)
' Specify whether derived keys are needed.
security.SetKeyDerivation(True)
' Create the custom binding.
Dim myBinding As New CustomBinding(security, New HttpTransportBindingElement())
' Create the Type instances for later use and the Uri for
' the base address.
Dim contractType As Type = GetType(ICalculator)
Dim serviceType As Type = GetType(Calculator)
Dim baseAddress As New Uri("https://localhost:8036/serviceModelSamples/")
' Create the ServiceHost and add an endpoint, then start
' the service.
Dim myServiceHost As New ServiceHost(serviceType, baseAddress)
myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator")
myServiceHost.Open()
SecurityBindingElement security = SecurityBindingElement.CreateMutualCertificateBindingElement();
// Use a secure session and specify that stateful SecurityContextToken security tokens are used.
security = SecurityBindingElement.CreateSecureConversationBindingElement(security, false);
// Specify whether derived keys are needed.
security.SetKeyDerivation(true);
// Create the custom binding.
CustomBinding myBinding = new CustomBinding(security, new HttpTransportBindingElement());
// Create the Type instances for later use and the Uri for
// the base address.
Type contractType = typeof(ICalculator);
Type serviceType = typeof(Calculator);
Uri baseAddress = new
Uri("https://localhost:8036/serviceModelSamples/");
// Create the ServiceHost and add an endpoint, then start
// the service.
ServiceHost myServiceHost =
new ServiceHost(serviceType, baseAddress);
myServiceHost.AddServiceEndpoint
(contractType, myBinding, "secureCalculator");
myServiceHost.Open();
При использовании проверки подлинности Windows в сочетании с маркером SCT с отслеживанием состояния WCF не заносит в свойство WindowsIdentity фактический идентификатор вызывающей стороны, но вместо этого задает это свойство как анонимное. Поскольку безопасность WCF должна воссоздавать содержимое контекста безопасности службы для каждого запроса из входящего маркера SCT, сервер не ведет учета безопасных сеансов в памяти. Поскольку выполнить сериализацию экземпляра WindowsIdentity в маркер SCT невозможно, свойство WindowsIdentity возвращает анонимный идентификатор.
Следующая конфигурация демонстрирует это поведение.
<customBinding>
<binding name="Cancellation">
<textMessageEncoding />
<security
requireSecurityContextCancellation="false">
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>