如何从客户端请求中获取X509证书

15

我有一个使用证书进行安全保护的Web服务。 现在,我想通过查看证书指纹来标识客户端。这意味着我在我的服务中有一个指纹列表,与某些用户相关联。

实际上,我的第一个问题(有点不相关)是:这是一个好方法还是我应该仍然引入一些用户名密码构造?

第二个问题是:我如何获取客户端用于连接到Web服务的证书,以便我可以在服务端读取指纹。

我已经阅读了很多关于此的内容(比如这篇帖子:如何在Web服务中获取客户端发送的X509Certificate?),但没有找到答案。

由于我没有HTTPContext,所以那不是一个选项。在上面提到的帖子中,提到了Context.Request.ClientCertificate.Certificate,但我想他们也是指的HTTPContext。此外,在web.config中添加<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />也不是一个选项。


所以你正在使用WCF和一些非HTTP绑定(TCP)? - Giedrius
2个回答

20

这是我们在Web服务的构造函数中实现的方式:

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

1
我正在我的请求中设置客户端证书,但在我的情况下,我正在命中第二个if检查,ClaimSets是一个空列表。服务配置需要做什么? - Stealth Rabbi
我不记得了,抱歉 :S - albertjan

4
我认为这种方法没有问题,只要在您可以控制证书分发并确保它们安全存储的环境中使用该服务。
假设这是一个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>

谢谢,我会尝试一下!等我搞清楚了,我会标记你的答案。 - Bas Slagter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接