Конечно, вам просто нужно проделать небольшую работу, чтобы начать работу с пользовательского элемента расширения привязки безопасности, описывающего токены, и какой из них следует использовать для подписи / подтверждения.В целях объяснения я буду считать, что вы всегда хотите, чтобы и сертификат, и имя пользователя / пароль были переданы.
В пользовательском элементе привязки вам нужно будет создать TransportSecurityBindingElement
и добавьте к нему параметры токена.Существует три коллекции для добавления параметров токена: SignedEncrypted
, Signed
и Endorsing
.Для сценария, о котором мы здесь говорим, я рекомендую добавить UserNameSecurityTokenParameters
в коллекцию SignedEncrypted
и X509SSecurityTokenParameters
в коллекцию Endorsing
.Это означает, что достоверность / целостность сообщения обеспечивается токеном сертификата, а не именем пользователя / паролем, и токен имени пользователя / пароля будет подписан и , зашифрованными токеном сертификата.Это будет выглядеть примерно так:
public class MySecurityBindingElement : BindingElementExtensionElement
{
public override void ApplyConfiguration(BindingElement bindingElement)
{
base.ApplyConfiguration(bindingElement);
TransportSecurityBindingElement transportSecurityBindingElement = (TransportSecurityBindingElement)bindingElement;
transportSecurityBindingElement.EndpointSupportingTokenParameters.SignedEncrypted.Add(new UserNameSecurityTokenParameters());
transportSecurityBindingElement.EndpointSupportingTokenParameters.Endorsing.Add(new X509SecurityTokenParameters
{
InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient,
ReferenceStyle = SecurityTokenReferenceStyle.Internal,
RequireDerivedKeys = false,
X509ReferenceStyle = X509KeyIdentifierClauseType.Any
});
}
protected override BindingElement CreateBindingElement()
{
TransportSecurityBindingElement result = new TransportSecurityBindingElement
{
IncludeTimestamp = true,
LocalClientSettings.DetectReplays = false,
LocalServiceSettings.DetectReplays = false
};
this.ApplyConfiguration(result);
return result;
}
}
Затем, с точки зрения клиента, вы просто должны установить и сертификат, и пароль для имени пользователя, установленные для каждого канала, который вы используете для связи с сервером.,Вы можете сделать это во время выполнения, установив свойства в свойство Credentials
либо ChannelFactory
, либо стандартного WCF, ClientBase
proxy класса.Еще одна вещь, которую вы можете сделать, это установить сертификат клиента с помощью поведения конечной точки, например, так:
<endpointBehavior>
<behavior name="MyBehavior">
<clientCredentials>
<clientCertificate findValue="MySubject" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
</clientCredentials>
</behavior>
</endpointBehavior>
Сделано таким образом, вам только когда-либо потребуется явно установить имя пользователя / пароль во время выполнения.
Наконец, в STS вы можете прочитать токены, указанные пользователем через свойство OperationContext::SupportingTokens
.В коллекции вы найдете экземпляры UserNameSecurityToken
и X509SecurityToken
, и оттуда вы можете использовать их для аутентификации звонящего.