简体   繁体   English

如何从客户端请求获取X509Certificate

[英]How to get the X509Certificate from a client request

I have a web-service which I secured using certificates. 我有一个使用证书保护的网络服务。 Now, I want to identify the client by looking at the certificate thumbprint. 现在,我想通过查看证书指纹来识别客户端。 This means that I have a list of thumbprints on my service somewhere that are linked to some user. 这意味着我的服务上有一些指纹列表,这些指纹链接到某个用户。

Actually, my first question (a little off-topic) is: is this a good approach or should I still introduce some username password construction? 实际上,我的第一个问题(有点偏离主题)是:这是一个好方法还是我还应该引入一些用户名密码构造?

Second question is: how can I get the certificate that the client used to connect to the web-service so I can read the thumbprint at the service side. 第二个问题是:我如何获得客户端用于连接到Web服务的证书,以便我可以在服务端读取指纹。

I did read a lot about it (like this post: How do I get the X509Certificate sent from the client in web service? ) but could not find an answer. 我确实读了很多关于它的内容(比如这篇文章: 如何从Web服务中的客户端发送X509Certificate? )但找不到答案。

I have no HTTPContext, so that is not an option. 我没有HTTPContext,所以这不是一个选项。 In the post mentioned above is spoken about Context.Request.ClientCertificate.Certificate but I guess they mean the HTTPContext there as well. 在上面提到的帖子中是关于Context.Request.ClientCertificate.Certificate但我想它们也意味着HTTPContext Also adding <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> to the web.config is also not an option. 另外,将<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />到web.config也不是一个选项。

this is how we do this in the constructor of our webservice: 这是我们在webservice的构造函数中执行此操作的方式:

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

I don't think there is anything wrong with this approach, as long as this service is used in an environment where you can control certificate distribution and ensure they are stored securely. 我不认为这种方法有任何问题,只要在您可以控制证书分发并确保它们安全存储的环境中使用此服务。

Assuming this is a WCF service, you can get the certificate the client is presenting using a class that inherits from ServiceAuthorizationManager . 假设这是一个WCF服务,您可以使用从ServiceAuthorizationManager继承的类获取客户端提供的证书。 Something like this will do the job: 这样的事情可以完成这项工作:

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");
    }
}

You then need to change your configuration at the server to use this authorization manager: 然后,您需要在服务器上更改配置以使用此授权管理器:

<system.serviceModel>

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

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

                ...

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

    ...

</system.serviceModel>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM