如何从客户端请求获取X509Certificate
我有一个使用证书保护的网络服务。 现在,我想通过查看证书指纹来识别客户端。 这意味着我的服务上有一些指纹列表,这些指纹链接到某个用户。
实际上,我的第一个问题(有点偏离主题)是:这是一个好方法还是我还应该引入一些用户名密码构造?
第二个问题是:我如何获得客户端用于连接到Web服务的证书,以便我可以在服务端读取指纹。
我确实读了很多关于它的内容(比如这篇文章: 如何从Web服务中的客户端发送X509Certificate? )但找不到答案。
我没有HTTPContext,所以这不是一个选项。 在上面提到的post中提到了Context.Request.ClientCertificate.Certificate
但我想它们也意味着HTTPContext
。 另外,将到web.config也不是一个选项。
这是我们在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
我不认为这种方法有任何问题,只要在您可以控制证书分发并确保安全存储的环境中使用此服务。
假设这是一个WCF服务,您可以使用inheritance自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"); } }
然后,您需要在服务器上更改配置以使用此授权管理器:
... ...