Можно ли иметь WCF STS с именем пользователя / паролем и клиентским сертификатом? - PullRequest
3 голосов
/ 24 мая 2011

Я использую WIF с STS.Все работает отлично, и клиент аутентифицируется, отправляя имя пользователя / пароль в учетных данных.

Мы устанавливаем клиентов на сайтах клиентов.Я хотел бы, чтобы каждый клиент использовал свой собственный сертификат для своих клиентов.Причиной этого является то, что проверка «клиент-сайт» невозможна.Я могу деактивировать некоторые учетные записи пользователей, но не могу отключить сразу все клиенты, установленные на клиенте.
Если бы у каждого клиента был свой сертификат, я мог бы отозвать этот сертификат, и ни один клиент этого клиента больше не мог бы подключиться.

Я не смог найти способ заставить клиента установить свой сертификат для связи.Обычно это происходит автоматически, когда режим аутентификации установлен на сертификат , но мне нужно установить его на windows , чтобы иметь возможность отправлять аутентификацию.

У кого-нибудь естьидея о том, как этого добиться?Или дайте мне знать, если это просто невозможно.

Приветствия.

1 Ответ

2 голосов
/ 24 мая 2011

Конечно, вам просто нужно проделать небольшую работу, чтобы начать работу с пользовательского элемента расширения привязки безопасности, описывающего токены, и какой из них следует использовать для подписи / подтверждения.В целях объяснения я буду считать, что вы всегда хотите, чтобы и сертификат, и имя пользователя / пароль были переданы.

В пользовательском элементе привязки вам нужно будет создать 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, и оттуда вы можете использовать их для аутентификации звонящего.

...