HttpRequestMessage.GetClientCertificate()不使用Azure功能

时间:2017-09-12 22:00:11

标签: azure azure-functions

我写过以下azure函数..(问题的快速和简短版本)

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;

namespace GranadaCoder.AzurePoc.AzureFunctionsOne
{
    public static class ClientCertificateTest
    {
        [FunctionName("ClientCertificateTestFunctionName")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, TraceWriter log)
        {
            try
            {
                System.Security.Cryptography.X509Certificates.X509Certificate2 cert = req.GetClientCertificate();

                X509Certificate2 headerCert = null;
                System.Net.Http.Headers.HttpRequestHeaders headers = req.Headers;
                if (headers.Any(x => x.Key.Equals("X-ARR-ClientCert", StringComparison.OrdinalIgnoreCase)))
                {
                    IEnumerable<string> headerValues = headers.GetValues("X-ARR-ClientCert");
                    if (null != headerValues)
                    {
                        var certHeader = headerValues.FirstOrDefault();
                        byte[] clientCertBytes = Convert.FromBase64String(certHeader);
                        headerCert = new X509Certificate2(clientCertBytes);
                    }
                }

                string msg = (null == cert ? "NO CERT :(" : string.Format("We got a cert! '{0}'", cert.Subject)) + " " + (null == headerCert ? "NO headerCert :(" : string.Format("We got a headerCert! '{0}'", headerCert.Subject));

                HttpContent content = req.Content;
                string contentString = content.ReadAsStringAsync().Result;

                msg += String.IsNullOrEmpty(contentString) ? ", no content" : ", " + contentString;

                return req.CreateResponse(HttpStatusCode.OK, msg);
            }
            catch (Exception ex)
            {
                string errorMsg = ex.Message; //  ExceptionHelper.GenerateFullFlatMessage(ex);
                log.Error(errorMsg);
                return req.CreateResponse(HttpStatusCode.BadRequest, errorMsg);
            }
        }
    }
}

我写了以下“客户”代码。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace GranadaCoder.SendWebRequests.ConsoleOne
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("START : {0}", System.Diagnostics.Process.GetCurrentProcess().ProcessName);

                X509Certificate2 clientCert = GetClientCertificate("MySelfSignedCertificatePrivateKeyVersion");
                WebRequestHandler requestHandler = new WebRequestHandler();
                requestHandler.ClientCertificates.Add(clientCert);

                HttpClient client = new HttpClient(requestHandler)
                {
                    BaseAddress = new Uri("http://localhost:7071/")
                };

                var pairs = new List<KeyValuePair<string, string>>
                {
                    new KeyValuePair<string, string>("login", "abc")
                };

                var postContent = new FormUrlEncodedContent(pairs);

                HttpResponseMessage hrm = client.PostAsync("api/ClientCertificateTestFunctionName", postContent).Result;
                hrm.EnsureSuccessStatusCode();
                if (hrm.IsSuccessStatusCode)
                {
                }

                HttpContent content = hrm.Content;
                string contentString = content.ReadAsStringAsync().Result;

                Console.WriteLine(hrm);
                Console.WriteLine(contentString);
            }
            catch(Exception ex)
            {
                string errorMsg = GenerateFullFlatMessage(ex, true);
                Console.WriteLine(errorMsg);
            }

            Console.WriteLine("END : {0}", System.Diagnostics.Process.GetCurrentProcess().ProcessName);
            Console.WriteLine(string.Empty);

            Console.WriteLine("Press ENTER to exit");
            Console.ReadLine();
        }

        private static X509Certificate2 GetClientCertificate(string subjectName)
        {
            X509Store userCaStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            try
            {
                userCaStore.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certificatesInStore = userCaStore.Certificates;
                X509Certificate2Collection findResult = certificatesInStore.Find(X509FindType.FindBySubjectName, subjectName, true);
                X509Certificate2 clientCertificate = null;
                if (findResult.Count == 1)
                {
                    clientCertificate = findResult[0];
                }
                else
                {
                    throw new Exception("Unable to locate the correct client certificate.");
                }
                return clientCertificate;
            }
            catch
            {
                throw;
            }
            finally
            {
                userCaStore.Close();
            }
        }

        private static string GenerateFullFlatMessage(Exception ex, bool showStackTrace)
        {
            string returnValue;

            StringBuilder sb = new StringBuilder();
            Exception nestedEx = ex;

            while (nestedEx != null)
            {
                if (!string.IsNullOrEmpty(nestedEx.Message))
                {
                    sb.Append(nestedEx.Message + System.Environment.NewLine);
                }

                if (showStackTrace && !string.IsNullOrEmpty(nestedEx.StackTrace))
                {
                    sb.Append(nestedEx.StackTrace + System.Environment.NewLine);
                }

                nestedEx = nestedEx.InnerException;
            }

            returnValue = sb.ToString();

            return returnValue;
        }
    }
}

客户端代码正确获取证书。 MySelfSignedCertificatePrivateKeyVersion是自签名的,它具有私钥。签署此自签名证书的CA位于我的信任根权限中。

Azure功能未看到客户端证书。

我的客户回复是:

“没有CERT :(,登录= abc”

为什么HttpRequestMessage.GetClientCertificate()失败?

我知道有些东西在起作用,因为我看到了azure函数和响应的“abc”。

注意,我在调试模式下在Visual Studio 2017中运行我的azure函数。

APPEND:

根据Tom-Sun的回答,当函数存在于azure中时,我能够使它工作。

这是我稍微修改过的客户代码。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace GranadaCoder.SendWebRequests.ConsoleOne
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ////ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

                /////////* Use the below to debug failed verification. */
                ////////ServicePointManager.ServerCertificateValidationCallback =
                ////////    new System.Net.Security.RemoteCertificateValidationCallback((
                ////////        sender,
                ////////        cert,
                ////////        chain,
                ////////        ssl) =>
                ////////{
                ////////    Console.WriteLine("ServerCertificateValidationCallback for Cert.Subject : '{0}'", cert.Subject);
                ////////    System.Net.HttpWebRequest hwr = sender as System.Net.HttpWebRequest;
                ////////    if (null != hwr)
                ////////    {
                ////////        SecurityShower.ShowHttpWebRequest(hwr);
                ////////    }

                ////////    //SecurityShower.ShowCertAndChain(cert, chain);
                ////////    return true;
                ////////});


                Console.WriteLine("START : {0}", System.Diagnostics.Process.GetCurrentProcess().ProcessName);

                /* the kind of cert matters this one works, this kind of  certificate  worked
                 X509Extension.X509KeyUsageExtension.KeyUsages = 'CrlSign, KeyCertSign' */
                string thumbPrint = "0123456789012345678901234567890123456789";

                /* certicate that would not work */
                /*X509Extension.X509KeyUsageExtension.KeyUsages = 'KeyEncipherment, DigitalSignature' */
                //thumbPrint = "1234567890123456789012345678901234567890";

                X509Certificate2 clientCert = GetClientCertificate(thumbPrint);
                WebRequestHandler requestHandler = new WebRequestHandler();
                requestHandler.ClientCertificates.Add(clientCert);

                /* local not working */
                string baseUrl = "http://localhost:7071/";
                string suffixUrl = "api/ClientCertificateTestFunctionName";

                /* remote (azure published */
                baseUrl = "https://yourFunctionNameHere.azurewebsites.net/";
                suffixUrl = "api/ClientCertificateTestFunctionName";

                /* some vodoo to create the queryString, the "code" value is gotten via the azure-portal "Get function URL" while on the properties page of the azure function... NOTE, I had to get this value before I change clientCertEnabled to true (aka, when it was clientCertEnabled was false)  after I changed clientCertEnabled to true, the "extra" querystring of the azure function was not showing */
                var builder = new UriBuilder("http://www.wontactuallybeused.com");
                builder.Port = -1;
                var query = System.Web.HttpUtility.ParseQueryString(builder.Query);
                query["code"] = "NotForYouToSee0123456789012345678901234567890123456789==";
                builder.Query = query.ToString();
                string url = builder.ToString();
                suffixUrl += builder.Query;

                HttpClient client = new HttpClient(requestHandler)
                {
                    BaseAddress = new Uri(baseUrl)
                };

                var pairs = new List<KeyValuePair<string, string>>
                {
                    new KeyValuePair<string, string>("login", "abc")
                };

                var postContent = new FormUrlEncodedContent(pairs);

                HttpResponseMessage hrm = client.PostAsync(suffixUrl, postContent).Result;
                //hrm.EnsureSuccessStatusCode();
                if (hrm.IsSuccessStatusCode)
                {
                }

                HttpContent content = hrm.Content;
                string contentString = content.ReadAsStringAsync().Result;

                Console.WriteLine(hrm);
                Console.WriteLine(contentString);
            }
            catch(Exception ex)
            {
                string errorMsg = GenerateFullFlatMessage(ex, true);
                Console.WriteLine(errorMsg);
            }

            Console.WriteLine("END : {0}", System.Diagnostics.Process.GetCurrentProcess().ProcessName);
            Console.WriteLine(string.Empty);

            Console.WriteLine("Press ENTER to exit");
            Console.ReadLine();
        }

        private static X509Certificate2 GetClientCertificate(string thumbprintValue)
        {
            thumbprintValue = System.Text.RegularExpressions.Regex.Replace(thumbprintValue, @"[^\da-zA-z]", string.Empty).ToUpper();
            X509Store userCaStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            try
            {
                userCaStore.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certificatesInStore = userCaStore.Certificates;
                X509Certificate2Collection findResult = certificatesInStore.Find(X509FindType.FindByThumbprint, thumbprintValue, true);
                X509Certificate2 clientCertificate = null;
                if (findResult.Count == 1)
                {
                    clientCertificate = findResult[0];
                }
                else
                {
                    throw new Exception("Unable to locate the correct client certificate.");
                }
                return clientCertificate;
            }
            catch
            {
                throw;
            }
            finally
            {
                userCaStore.Close();
            }
        }

        private static string GenerateFullFlatMessage(Exception ex, bool showStackTrace)
        {
            string returnValue;

            StringBuilder sb = new StringBuilder();
            Exception nestedEx = ex;

            while (nestedEx != null)
            {
                if (!string.IsNullOrEmpty(nestedEx.Message))
                {
                    sb.Append(nestedEx.Message + System.Environment.NewLine);
                }

                if (showStackTrace && !string.IsNullOrEmpty(nestedEx.StackTrace))
                {
                    sb.Append(nestedEx.StackTrace + System.Environment.NewLine);
                }

                nestedEx = nestedEx.InnerException;
            }

            returnValue = sb.ToString();

            return returnValue;
        }
    }
}

和一个可选的助手

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace MyNamespace
{
    public static class SecurityShower
    {
        public static void ShowHttpWebRequest(System.Net.HttpWebRequest hwr)
        {
            StringBuilder sb = new StringBuilder();
            if (null != hwr)
            {
                sb.Append("-----------------------------------------------HttpWebRequest" + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.Address.AbsolutePath='{0}'", hwr.Address.AbsolutePath) + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.Address.AbsoluteUri='{0}'", hwr.Address.AbsoluteUri) + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.Address='{0}'", hwr.Address) + System.Environment.NewLine);

                sb.Append(string.Format("HttpWebRequest.RequestUri.AbsolutePath='{0}'", hwr.RequestUri.AbsolutePath) + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.RequestUri.AbsoluteUri='{0}'", hwr.RequestUri.AbsoluteUri) + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.RequestUri='{0}'", hwr.RequestUri) + System.Environment.NewLine);

                foreach (X509Certificate cert in hwr.ClientCertificates)
                {
                    sb.Append("START*************************************************");
                    ShowX509Certificate(sb, cert);
                    sb.Append("END*************************************************");
                }
            }

            string result = sb.ToString();
            Console.WriteLine(result);
        }

        public static void ShowCertAndChain(X509Certificate2 cert)
        {
            X509Chain chain = new X509Chain();
            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
            chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;

            ////chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreCtlSignerRevocationUnknown &&
            ////X509VerificationFlags.IgnoreRootRevocationUnknown &&
            ////X509VerificationFlags.IgnoreEndRevocationUnknown &&
            ////X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown &&
            ////X509VerificationFlags.IgnoreCtlNotTimeValid;

            chain.Build(cert);

            ShowCertAndChain(cert, chain);
        }

        public static void ShowCertAndChain(X509Certificate cert, X509Chain chain)
        {
            StringBuilder sb = new StringBuilder();
            if (null != cert)
            {
                ShowX509Certificate(sb, cert);
            }

            if (null != chain)
            {
                sb.Append("-X509Chain(Start)-" + System.Environment.NewLine);
                ////sb.Append(string.Format("Cert.ChainStatus='{0}'", string.Join(",", chain.ChainStatus.ToList())) + System.Environment.NewLine);

                foreach (X509ChainStatus cstat in chain.ChainStatus)
                {
                    sb.Append(string.Format("X509ChainStatus::'{0}'-'{1}'", cstat.Status.ToString(), cstat.StatusInformation) + System.Environment.NewLine);
                }

                X509ChainElementCollection ces = chain.ChainElements;
                ShowX509ChainElementCollection(sb, ces);
                sb.Append("-X509Chain(End)-" + System.Environment.NewLine);
            }

            string result = sb.ToString();
            Console.WriteLine(result);
        }

        private static void ShowX509Extension(StringBuilder sb, int x509ExtensionCount, X509Extension ext)
        {
            sb.Append(string.Empty + System.Environment.NewLine);
            sb.Append(string.Format("--------X509ExtensionNumber(Start):{0}", x509ExtensionCount) + System.Environment.NewLine);
            sb.Append(string.Format("X509Extension.Critical='{0}'", ext.Critical) + System.Environment.NewLine);

            AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData);
            sb.Append(string.Format("Extension type: {0}", ext.Oid.FriendlyName) + System.Environment.NewLine);
            sb.Append(string.Format("Oid value: {0}", asndata.Oid.Value) + System.Environment.NewLine);
            sb.Append(string.Format("Raw data length: {0} {1}", asndata.RawData.Length, Environment.NewLine) + System.Environment.NewLine);
            sb.Append(asndata.Format(true) + System.Environment.NewLine);

            X509BasicConstraintsExtension basicEx = ext as X509BasicConstraintsExtension;
            if (null != basicEx)
            {
                sb.Append("-X509BasicConstraintsExtension-" + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509BasicConstraintsExtension.CertificateAuthority='{0}'", basicEx.CertificateAuthority) + System.Environment.NewLine);
            }

            X509EnhancedKeyUsageExtension keyEx = ext as X509EnhancedKeyUsageExtension;
            if (null != keyEx)
            {
                sb.Append("-X509EnhancedKeyUsageExtension-" + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509EnhancedKeyUsageExtension.EnhancedKeyUsages='{0}'", keyEx.EnhancedKeyUsages) + System.Environment.NewLine);
                foreach (Oid oi in keyEx.EnhancedKeyUsages)
                {
                    sb.Append(string.Format("------------EnhancedKeyUsages.Oid.FriendlyName='{0}'", oi.FriendlyName) + System.Environment.NewLine);
                    sb.Append(string.Format("------------EnhancedKeyUsages.Oid.Value='{0}'", oi.Value) + System.Environment.NewLine);
                }
            }

            X509KeyUsageExtension usageEx = ext as X509KeyUsageExtension;
            if (null != usageEx)
            {
                sb.Append("-X509KeyUsageExtension-" + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509KeyUsageExtension.KeyUsages='{0}'", usageEx.KeyUsages) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.CrlSign) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DataEncipherment) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DecipherOnly) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DigitalSignature='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DigitalSignature) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.EncipherOnly) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyAgreement) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyCertSign) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyEncipherment) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.None='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.None) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.NonRepudiation) != 0) + System.Environment.NewLine);
            }

            X509SubjectKeyIdentifierExtension skIdEx = ext as X509SubjectKeyIdentifierExtension;
            if (null != skIdEx)
            {
                sb.Append("-X509SubjectKeyIdentifierExtension-" + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509SubjectKeyIdentifierExtension.Oid='{0}'", skIdEx.Oid) + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509SubjectKeyIdentifierExtension.SubjectKeyIdentifier='{0}'", skIdEx.SubjectKeyIdentifier) + System.Environment.NewLine);
            }

            sb.Append(string.Format("--------X509ExtensionNumber(End):{0}", x509ExtensionCount) + System.Environment.NewLine);
        }

        private static void ShowX509Extensions(StringBuilder sb, string cert2SubjectName, X509ExtensionCollection extColl)
        {
            int x509ExtensionCount = 0;
            sb.Append(string.Format("--------ShowX509Extensions(Start):for:{0}", cert2SubjectName) + System.Environment.NewLine);
            foreach (X509Extension ext in extColl)
            {
                ShowX509Extension(sb, ++x509ExtensionCount, ext);
            }

            sb.Append(string.Format("--------ShowX509Extensions(End):for:{0}", cert2SubjectName) + System.Environment.NewLine);
        }

        private static void ShowX509Certificate2(StringBuilder sb, X509Certificate2 cert2)
        {
            if (null != cert2)
            {
                sb.Append(string.Format("X509Certificate2.SubjectName.Name='{0}'", cert2.SubjectName.Name) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.Subject='{0}'", cert2.Subject) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.Thumbprint='{0}'", cert2.Thumbprint) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.HasPrivateKey='{0}'", cert2.HasPrivateKey) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.Version='{0}'", cert2.Version) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.NotBefore='{0}'", cert2.NotBefore) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.NotAfter='{0}'", cert2.NotAfter) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.PublicKey.Key.KeySize='{0}'", cert2.PublicKey.Key.KeySize) + System.Environment.NewLine);

                ////List<X509KeyUsageExtension> keyUsageExtensions = cert2.Extensions.OfType<X509KeyUsageExtension>().ToList();
                ////List<X509Extension> extensions = cert2.Extensions.OfType<X509Extension>().ToList();

                ShowX509Extensions(sb, cert2.Subject, cert2.Extensions);
            }
        }

        private static void ShowX509ChainElementCollection(StringBuilder sb, X509ChainElementCollection ces)
        {
            int x509ChainElementCount = 0;
            foreach (X509ChainElement ce in ces)
            {
                sb.Append(string.Empty + System.Environment.NewLine);
                sb.Append(string.Format("----X509ChainElementNumber:{0}", ++x509ChainElementCount) + System.Environment.NewLine);
                sb.Append(string.Format("X509ChainElement.Cert.SubjectName.Name='{0}'", ce.Certificate.SubjectName.Name) + System.Environment.NewLine);
                sb.Append(string.Format("X509ChainElement.Cert.Issuer='{0}'", ce.Certificate.Issuer) + System.Environment.NewLine);
                sb.Append(string.Format("X509ChainElement.Cert.Thumbprint='{0}'", ce.Certificate.Thumbprint) + System.Environment.NewLine);
                sb.Append(string.Format("X509ChainElement.Cert.HasPrivateKey='{0}'", ce.Certificate.HasPrivateKey) + System.Environment.NewLine);

                X509Certificate2 cert2 = ce.Certificate as X509Certificate2;
                ShowX509Certificate2(sb, cert2);

                ShowX509Extensions(sb, cert2.Subject, ce.Certificate.Extensions);
            }
        }

        private static void ShowX509Certificate(StringBuilder sb, X509Certificate cert)
        {
            sb.Append("-----------------------------------------------" + System.Environment.NewLine);
            sb.Append(string.Format("Cert.Subject='{0}'", cert.Subject) + System.Environment.NewLine);
            sb.Append(string.Format("Cert.Issuer='{0}'", cert.Issuer) + System.Environment.NewLine);

            sb.Append(string.Format("Cert.GetPublicKey().Length='{0}'", cert.GetPublicKey().Length) + System.Environment.NewLine);

            X509Certificate2 cert2 = cert as X509Certificate2;
            ShowX509Certificate2(sb, cert2);
        }
    }
}

好读(

http://www.razibinrais.com/secure-web-api-with-client-certificate/

1 个答案:

答案 0 :(得分:2)

  

为什么HttpRequestMessage.GetClientCertificate()失败?

我在你身边测试你的代码。我发现如果我在本地调试它,那么我可以在Azure平台上重现你提到的,如果我将 clientCertEnabled 更改为true,那么它会按预期工作。更多详情请参阅Configure Web App for Client Certificate Authentication。如果有人如何在本地启用clientCertEnabled请添加评论。

  

要设置您的Web应用程序以要求客户端证书,您需要为Web应用程序添加clientCertEnabled站点设置并将其设置为true。此设置目前无法通过Portal中的管理经验获得,并且需要使用REST API来实现此目的。   您可以使用ARMClient工具轻松编写REST API调用。使用该工具登录后,您需要发出以下内容

ARMClient PUT subscriptions/{Subscription Id}/resourcegroups/{Resource Group Name}/providers/Microsoft.Web/sites/{Website Name}?api-version=2015-04-01 @enableclientcert.json -verbose

我用azure resources

更改clientCertEnabled

enter image description here

使用客户端代码进行测试:

enter image description here

注意:目前,如果我们将clientCertEnabled设置为true,那么对azure函数的所有请求都需要认证