如何从客户端请求获取 X509Certificate

发布于 2024-12-06 04:21:57 字数 555 浏览 1 评论 0原文

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

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

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

我确实阅读了很多相关内容(例如这篇文章:如何在 Web 服务中获取从客户端发送的 X509Certificate? )但找不到答案。

我没有 HTTPContext,所以这不是一个选项。在上面提到的帖子中谈到了 Context.Request.ClientCertificate.Certificate 但我猜他们也指的是 HTTPContext 。另外,将 添加到 web.config 也不是一个选项。

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.

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.

I have no HTTPContext, so that is not an option. In the post mentioned above is spoken about Context.Request.ClientCertificate.Certificate but I guess they mean the HTTPContext there as well. Also adding <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> to the web.config is also not an option.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

生生漫 2024-12-13 04:21:57

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

this is how we do this in the constructor of our 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
橘虞初梦 2024-12-13 04:21:57

我认为这种方法没有任何问题,只要在可以控制证书分发并确保它们安全存储的环境中使用该服务即可。

假设这是一个 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>

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. 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文