Подтвердить что ты не робот

Как получить сертификат X509 от запроса клиента

У меня есть веб-сервис, который я получил с помощью сертификатов. Теперь я хочу идентифицировать клиента, посмотрев на отпечаток сертификата. Это означает, что у меня есть список отпечатков на моей службе где-то, которые связаны с некоторым пользователем.

На самом деле, мой первый вопрос (немного не по теме): это хороший подход или мне еще нужно ввести некоторую конструкцию паролей имени пользователя?

Второй вопрос: как я могу получить сертификат, который клиент использовал для подключения к веб-сервису, чтобы я мог прочитать отпечаток на стороне службы.

Я много читал об этом (например, этот пост: Как мне получить сертификат X509, отправленный клиентом в веб-службе?), но не смог найти ответ.

У меня нет HTTPContext, так что это не вариант. В упомянутом выше сообщении говорится о Context.Request.ClientCertificate.Certificate, но я думаю, что они также означают HTTPContext. Кроме того, добавление <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> в web.config также не является вариантом.

4b9b3361

Ответ 1

так мы делаем это в конструкторе нашего веб-сервиса:

if (OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets == null)
    throw new SecurityException ("No claimset service configured wrong");

if (OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets.Count <= 0)
    throw new SecurityException ("No claimset service configured wrong");


var cert = ((X509CertificateClaimSet) OperationContext.Current.ServiceSecurityContext.
            AuthorizationContext.ClaimSets[0]).X509Certificate;

//this contains the thumbprint
cert.Thumbprint

Ответ 2

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

Предполагая, что это служба WCF, вы можете получить сертификат, который клиент представляет, используя класс, который наследует от ServiceAuthorizationManager. Что-то вроде этого выполнит работу:

public class CertificateAuthorizationManager : ServiceAuthorizationManager
{
    protected override bool CheckAccessCore(OperationContext operationContext)
    {
        if (!base.CheckAccessCore(operationContext))
        {
            return false;
        }

        string thumbprint = GetCertificateThumbprint(operationContext);

        // TODO: Check the thumbprint against your database, then return true if found, otherwise false
    }

    private string GetCertificateThumbprint(OperationContext operationContext)
    {
        foreach (var claimSet in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
        {
            foreach (Claim claim in claimSet.FindClaims(ClaimTypes.Thumbprint, Rights.Identity))
            {
                string tb = BitConverter.ToString((byte[])claim.Resource);
                tb = tb.Replace("-", "");
                return tb;
            }
        }

        throw new System.Security.SecurityException("No client certificate found");
    }
}

Затем вам нужно изменить конфигурацию на сервере, чтобы использовать этот диспетчер авторизации:

<system.serviceModel>

    <behaviors>
        <serviceBehaviors>
            <behavior name="MyServerBehavior">

                <serviceAuthorization serviceAuthorizationManagerType="myNamespace.CertificateAuthorizationManager, myAssembly"/>

                ...

            </behavior>
        </serviceBehaviors>
    </behaviors>

    ...

</system.serviceModel>