无法使用自签名客户端证书验证对ASP.NET MVC3服务的调用 [英] Cannot authenticate a call to ASP.NET MVC3 service with a self-signed client certificate
问题描述
我有一个ASP.NET MVC3服务运行在IIS 7.5与.NET Framework 4.5,我想要安全访问其中一个子路径与客户端证书。对于那个子路径,我制作了一个带有特殊属性的控制器,它将访问请求客户端证书。
I have an ASP.NET MVC3 service running in IIS 7.5 with .NET Framework 4.5 where I want to secure access to one of the subpaths with a client certificate. For that subpath I crafted a controller with is labeled with a specially crafted attribute which would access the request client certificate
public class CheckCertAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(
ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Headers.Add(
"CheckCertAttribute", "entered");
var cert = filterContext.HttpContext.Request.ClientCertificate;
// check the cert here, optionally return HTTP 403
}
}
$ b b
最初 OnActionExecuting()
正在被调用,但证书
为空。原来我需要在web.config中启用 SslNegotiateCert
:
Initially OnActionExecuting()
is being invoked but Certificate
is null. Turns out I need to enable SslNegotiateCert
in web.config:
<location path="PathOfInterest">
<system.webServer>
<security>
<access sslFlags="SslNegotiateCert"/>
</security>
</system.webServer>
</location>
一旦我这样做,客户端总是接收HTTP 403,并且该属性不再被调用。
Once I do this the client always receives HTTP 403 and the attribute is no longer invoked.
客户端证书是自签名的,并导出为.pfx(使用私钥),所以我想问题是,一旦它到达服务器端,服务器不喜欢它拒绝接受它并通过。客户端使用 HttpWebRequest
:
The client certificate is self-signed and exported as .pfx (with a private key) so I guess the problem is that once it arrives on the server side the server doesn't like it and refuses to accept it and pass through. The client side uses HttpWebRequest
:
var cert = new X509Certificate2(pathToPfx, password);
var request = (HttpWebRequest)WebRequest.Create("https://my.company.com/PathOfInterest");
request.ClientCertificates.Add(cert);
request.GetResponse();
我已经使用这种方法,它工作。第一种情况是当客户端证书不是自签名,但是由中间证书签名,而中间证书又由一些受信任的根权威机构签名 - 在这种情况下,我的服务配置非常相似,只是接受它。第二种情况是使用自签名的客户端证书来进行Azure管理服务调用,但在这种情况下,我不知道如何配置服务器端。
I've already used this approach earlier and it worked. The first case was when the client certificate was not self-signed but was signed by an intermediate certificate which in turn was signed by some trusted root authority - in this case my service configured very similarly would receive it just fine. The second case was using a self-signed client certificate to make Azure Management Service calls but in this case I have no idea how the server side is configured.
得出结论,这是证书的自签名性质,使其不工作。我有这样做额外的 - 可能添加一些东西到web.config或添加证书到服务器端的一些证书存储。
I therefore came to conclusion that it's a self-signed nature of the certificate which makes it "not working". I have so do something extra - perhaps add something into web.config or add the certificate into some certificate store on the server side. I just have no idea what this should be.
如何使此设置生效?
推荐答案
IIS尝试与客户端协商互相信任的连接,因为客户端证书是自签名的,因此拒绝信任它。
IIS tries to "negotiate" a mutually trusted connection with the client and because the client certificate is self-signed it refuses to trust it.
您的选项:
- 使用知名认证机构颁发的证书。
- 运行您自己的CA基础架构,将其根CA证书添加到服务机器的受信任的根证书存储区中
- 将自签名证书添加到服务计算机的受信任根目录中。 这可能会导致微妙而严重的安全风险。我个人反对此选项,因为它感觉真的不安全。
- 切换到不使用客户端证书的其他身份验证方案。
- Use a certificate issued by a well known certificate authority. This would work but you'll have to reissue the certificate every year or so.
- Run your own CA infrastructure, add its root CA certificate into "trusted root" certificate store of the service machines and issue certificate signed with that root (likely via intermediate certificates).
- Add the self-signed certificate into "trusted root" of the service machines. This may induce subtle yet serious security risks. I personally am against this option because it feels really unsafe.
- Switch to some other authentication scheme which doesn't use client certificates.
这篇关于无法使用自签名客户端证书验证对ASP.NET MVC3服务的调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!