如何从客户端请求中获取 X509Certificate

Posted

技术标签:

【中文标题】如何从客户端请求中获取 X509Certificate【英文标题】:How to get the X509Certificate from a client request 【发布时间】:2011-11-23 14:45:28 【问题描述】:

我有一个使用证书保护的网络服务。 现在,我想通过查看证书指纹来识别客户端。这意味着我的服务上有一个链接到某个用户的指纹列表。

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

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

我确实阅读了很多关于它的信息(比如这篇文章:How do I get the X509Certificate sent from the client in web service?),但找不到答案。

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

【问题讨论】:

那么您使用的是 WCF 和一些非 http 绑定 (tcp)? 【参考方案1】:

这就是我们在 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

【讨论】:

我在我的请求中设置了一个客户端证书,但在我的情况下,我正在点击第二个 if-check,ClaimSets 是一个空列表。服务配置需要做什么? 我不记得很抱歉:S【参考方案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>

【讨论】:

谢谢,我会试一试!一旦我弄清楚了,就会标记你的答案。

以上是关于如何从客户端请求中获取 X509Certificate的主要内容,如果未能解决你的问题,请参考以下文章

如何配置 WCF 以通过 Internet 使用 x509 证书?

如何从 Java 中的 X509Certificate 中提取 CN?

如何从 X509Store 加载受密码保护的证书?

如何在Java中检索/计算X509证书的指纹?

Helm 从 pod 内部使用“x509:由未知机构签名的证书”获取错误

cURL error 60: SSL certificate problem: unable to get local issuer certifica 解决