Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# OnAuthorization(HttpActionContext)中没有证书_C#_Security_Asp.net Web Api_Ssl Certificate_Client Certificates - Fatal编程技术网

C# OnAuthorization(HttpActionContext)中没有证书

C# OnAuthorization(HttpActionContext)中没有证书,c#,security,asp.net-web-api,ssl-certificate,client-certificates,C#,Security,Asp.net Web Api,Ssl Certificate,Client Certificates,我已经从这个示例创建了CertificateTestController和ValuesController . 如果您从用户Ogglas向下滚动到“更新”。我以他为例,让“CertificateTestController”工作,在那里我可以从我的存储中获取证书并将其添加到“处理程序”中。当我调用“ValuesController”时,没有证书被初始化 X509Certificate2 cert = actionContext.Request.GetClientCertificate(); 这

我已经从这个示例创建了CertificateTestController和ValuesController . 如果您从用户Ogglas向下滚动到“更新”。我以他为例,让“CertificateTestController”工作,在那里我可以从我的存储中获取证书并将其添加到“处理程序”中。当我调用“ValuesController”时,没有证书被初始化

X509Certificate2 cert = actionContext.Request.GetClientCertificate();
这是我拥有的完整代码

值控制器

{
    [RequireSpecificCert]
    public class ValuesController : ApiController
    {
        // GET api/values
        public IHttpActionResult Get()
        {
            return Ok("It works!");
        }

        public class RequireSpecificCertAttribute : AuthorizationFilterAttribute
        {
            public override void OnAuthorization(HttpActionContext actionContext)
            {

                if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
                {
                    actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                    {
                        ReasonPhrase = "HTTPS Required"
                    };
                }
                else
                {
                    X509Certificate2 cert = actionContext.Request.GetClientCertificate();
                    X509Certificate2 cert2 = actionContext.RequestContext.ClientCertificate;

                    if (cert == null)
                    {
                        actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                        {
                            ReasonPhrase = "Client Certificate Required"
                        };
                    }
                    else
                    {
                        X509Chain chain = new X509Chain();

                        //Needed because the error "The revocation function was unable to check revocation for the certificate" happened to me otherwise
                        chain.ChainPolicy = new X509ChainPolicy()
                        {
                            RevocationMode = X509RevocationMode.NoCheck,
                        };
                        try
                        {
                            var chainBuilt = chain.Build(cert);
                            Debug.WriteLine(string.Format("Chain building status: {0}", chainBuilt));

                            var validCert = CheckCertificate(chain, cert);

                            if (chainBuilt == false || validCert == false)
                            {
                                actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                                {
                                    ReasonPhrase = "Client Certificate not valid"
                                };
                                foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                                {
                                    Debug.WriteLine(string.Format("Chain error: {0} {1}", chainStatus.Status, chainStatus.StatusInformation));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.ToString());
                        }
                    }

                    base.OnAuthorization(actionContext);
                }
            }

            private bool CheckCertificate(X509Chain chain, X509Certificate2 cert)
            {
                var rootThumbprint = WebConfigurationManager.AppSettings["rootThumbprint"].ToUpper().Replace(" ", string.Empty);

                var clientThumbprint = WebConfigurationManager.AppSettings["clientThumbprint"].ToUpper().Replace(" ", string.Empty);

                //Check that the certificate have been issued by a specific Root Certificate
                var validRoot = chain.ChainElements.Cast<X509ChainElement>().Any(x => x.Certificate.Thumbprint.Equals(rootThumbprint, StringComparison.InvariantCultureIgnoreCase));

                //Check that the certificate thumbprint matches our expected thumbprint
                var validCert = cert.Thumbprint.Equals(clientThumbprint, StringComparison.InvariantCultureIgnoreCase);

                return validRoot && validCert;
            }
        }
{
    [RoutePrefix("api/certificatetest")]
    public class CertificateTestController : ApiController
    {
        public IHttpActionResult Get()
        {
            var handler = new WebRequestHandler();
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.ClientCertificates.Add(GetClientCert());
            handler.UseProxy = false;
            var client = new HttpClient(handler);
            var result = client.GetAsync("https://localhost:44301//values").GetAwaiter().GetResult();
            var resultString = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            return Ok(resultString);
        }

        private static X509Certificate GetClientCert()
        {
            X509Store store = null;
            try
            {
                store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

                var certificateSerialNumber = "2bc034466b6960d2fee84d86e6c2532a".ToUpper().Replace(" ", string.Empty);

                var cert = store.Certificates.Cast<X509Certificate>().FirstOrDefault(x => x.GetSerialNumberString().Equals(certificateSerialNumber, StringComparison.InvariantCultureIgnoreCase));
                return cert;
            }
            finally
            {
                store.Close();
            }
        }
    }
}
{
[要求特定证书]
公共类值控制器:ApiController
{
//获取api/值
public IHttpActionResult Get()
{
返回Ok(“它工作了!”);
}
公共类RequireSpecificCertAttribute:AuthorizationFilterAttribute
{
授权时的公共覆盖无效(HttpActionContext actionContext)
{
if(actionContext.Request.RequestUri.Scheme!=Uri.UriSchemeHttps)
{
actionContext.Response=新的HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase=“需要HTTPS”
};
}
其他的
{
X509Certificate2Cert=actionContext.Request.GetClientCertificate();
X509Certificate2 cert2=actionContext.RequestContext.ClientCertificate;
如果(证书==null)
{
actionContext.Response=新的HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase=“需要客户端证书”
};
}
其他的
{
X509Chain chain=新的X509Chain();
//需要,因为“吊销功能无法检查证书的吊销”错误发生在我身上
chain.ChainPolicy=new X509ChainPolicy()
{
RevocationMode=X509RevocationMode.NoCheck,
};
尝试
{
var chainbuild=chain.Build(证书);
WriteLine(string.Format(“链构建状态:{0}”,chainbuilded));
var validCert=检查证书(链、证书);
if(chainbuild==false | | validCert==false)
{
actionContext.Response=新的HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase=“客户端证书无效”
};
foreach(X509ChainStatus chainStatus在chain.chainStatus中的chainStatus)
{
WriteLine(string.Format(“链错误:{0}{1}”,chainStatus.Status,chainStatus.StatusInformation));
}
}
}
捕获(例外情况除外)
{
Debug.WriteLine(例如ToString());
}
}
基于授权(actionContext);
}
}
私人bool检查证书(X509Chain chain,X509Certificate2证书)
{
var rootThumbprint=WebConfigurationManager.AppSettings[“rootThumbprint”].ToUpper().Replace(“,string.Empty);
var clientThumbprint=WebConfigurationManager.AppSettings[“clientThumbprint”].ToUpper().Replace(“,string.Empty);
//检查证书是否由特定的根证书颁发
var validRoot=chain.ChainElements.Cast().Any(x=>x.Certificate.Thumbprint.Equals(rootThumbprint,StringComparison.InvariantCultureIgnoreCase));
//检查证书指纹是否与预期指纹匹配
var validCert=cert.Thumbprint.Equals(clientThumbprint,StringComparison.invariantCultureInogoreCase);
返回validRoot&&validCert;
}
}
使用下面的CertificateTestController调用上面的值控制器

{
    [RequireSpecificCert]
    public class ValuesController : ApiController
    {
        // GET api/values
        public IHttpActionResult Get()
        {
            return Ok("It works!");
        }

        public class RequireSpecificCertAttribute : AuthorizationFilterAttribute
        {
            public override void OnAuthorization(HttpActionContext actionContext)
            {

                if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
                {
                    actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                    {
                        ReasonPhrase = "HTTPS Required"
                    };
                }
                else
                {
                    X509Certificate2 cert = actionContext.Request.GetClientCertificate();
                    X509Certificate2 cert2 = actionContext.RequestContext.ClientCertificate;

                    if (cert == null)
                    {
                        actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                        {
                            ReasonPhrase = "Client Certificate Required"
                        };
                    }
                    else
                    {
                        X509Chain chain = new X509Chain();

                        //Needed because the error "The revocation function was unable to check revocation for the certificate" happened to me otherwise
                        chain.ChainPolicy = new X509ChainPolicy()
                        {
                            RevocationMode = X509RevocationMode.NoCheck,
                        };
                        try
                        {
                            var chainBuilt = chain.Build(cert);
                            Debug.WriteLine(string.Format("Chain building status: {0}", chainBuilt));

                            var validCert = CheckCertificate(chain, cert);

                            if (chainBuilt == false || validCert == false)
                            {
                                actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                                {
                                    ReasonPhrase = "Client Certificate not valid"
                                };
                                foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                                {
                                    Debug.WriteLine(string.Format("Chain error: {0} {1}", chainStatus.Status, chainStatus.StatusInformation));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.ToString());
                        }
                    }

                    base.OnAuthorization(actionContext);
                }
            }

            private bool CheckCertificate(X509Chain chain, X509Certificate2 cert)
            {
                var rootThumbprint = WebConfigurationManager.AppSettings["rootThumbprint"].ToUpper().Replace(" ", string.Empty);

                var clientThumbprint = WebConfigurationManager.AppSettings["clientThumbprint"].ToUpper().Replace(" ", string.Empty);

                //Check that the certificate have been issued by a specific Root Certificate
                var validRoot = chain.ChainElements.Cast<X509ChainElement>().Any(x => x.Certificate.Thumbprint.Equals(rootThumbprint, StringComparison.InvariantCultureIgnoreCase));

                //Check that the certificate thumbprint matches our expected thumbprint
                var validCert = cert.Thumbprint.Equals(clientThumbprint, StringComparison.InvariantCultureIgnoreCase);

                return validRoot && validCert;
            }
        }
{
    [RoutePrefix("api/certificatetest")]
    public class CertificateTestController : ApiController
    {
        public IHttpActionResult Get()
        {
            var handler = new WebRequestHandler();
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.ClientCertificates.Add(GetClientCert());
            handler.UseProxy = false;
            var client = new HttpClient(handler);
            var result = client.GetAsync("https://localhost:44301//values").GetAwaiter().GetResult();
            var resultString = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            return Ok(resultString);
        }

        private static X509Certificate GetClientCert()
        {
            X509Store store = null;
            try
            {
                store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

                var certificateSerialNumber = "2bc034466b6960d2fee84d86e6c2532a".ToUpper().Replace(" ", string.Empty);

                var cert = store.Certificates.Cast<X509Certificate>().FirstOrDefault(x => x.GetSerialNumberString().Equals(certificateSerialNumber, StringComparison.InvariantCultureIgnoreCase));
                return cert;
            }
            finally
            {
                store.Close();
            }
        }
    }
}
{
[RoutePrefix(“api/certificatetest”)]
公共类CertificateTestController:ApiController
{
public IHttpActionResult Get()
{
var handler=新的WebRequestHandler();
handler.ClientCertificateOptions=ClientCertificateOptions.Manual;
Add(GetClientCert());
handler.UseProxy=false;
var client=新的HttpClient(处理程序);
var result=client.GetAsync(“https://localhost:44301//values).GetAwaiter().GetResult();
var resultString=result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
返回Ok(结果字符串);
}
私有静态X509证书GetClientCert()
{
X509Store=null;
尝试
{
store=new X509Store(StoreName.My,StoreLocation.LocalMachine);
store.Open(OpenFlags.openingonly | OpenFlags.ReadOnly);
var certificateSerialNumber=“2BC03446B6960D2fee84D86E6C2532A”.ToUpper().Replace(“,string.Empty”);
var cert=store.Certificates.Cast().FirstOrDefault(x=>x.GetSerialNumberString().Equals(certificateSerialNumber,StringComparison.InvariantCultureIgnoreCase));
返回证书;
}
最后
{
store.Close();
}
}
}
}

请帮助!

以下是我在试图解决问题的过程中回答的问题
<appSettings>
            <add key="webpages:Version" value="3.0.0.0" />
            <add key="webpages:Enabled" value="false" />
            <add key="ClientValidationEnabled" value="true" />
            <add key="UnobtrusiveJavaScriptEnabled" value="true" />
            <add key="rootThumbprint" value="change"/>
            <add key="clientThumbprint" value="change"/>
<add key="certificateSerialNumber" value="change"/>
</appSettings>
var certificateSerialNumber = WebConfigurationManager.AppSettings["certificateSerialNumber"].ToUpper().Replace(" ", string.Empty);