4

私は非常に奇妙な問題を抱えています。azure クラウド サービスに webrole を発行しました。このプロジェクトでは、webrole が Azure Rest API を呼び出す必要があります。ローカル エミュレーターで応答を取得できますが、Azure に発行すると、403 禁止エラーが発生します。証明書を Azure にインストールしたことは確かです。

このエラーは、次の手順で再現できます。

  1. まず、以下のリンクで証明書を作成します: http://msdn.microsoft.com/en-us/library/windowsazure/gg651127.aspx
  2. Webrole を使用してクラウド サービスを作成し、Azure portal で証明書を使用して、クラウド サービスの証明書と webrole->property->certificate を作成します。
  3. プロジェクトを公開します。
  4. Web ロール インスタンスにリモート ログインします。
  5. ローカルでコンソール アプリケーションを作成し、デバッグ フォルダーをリモート インスタンスにコピーして、リモート アプリケーションで exe を実行します。アプリケーションがローカルで完全に実行できることがわかりますが、Azure インスタンスでは、証明書を見つけることができるように見えますが、それでも 403 禁止エラーが発生します。

コンソール アプリのコード:

static void Main(string[] args)
    {
        try
        {
            // X.509 certificate variables.
            X509Store certStore = null;
            X509Certificate2Collection certCollection = null;
            X509Certificate2 certificate = null;

            // Request and response variables.
            HttpWebRequest httpWebRequest = null;
            HttpWebResponse httpWebResponse = null;

            // Stream variables.
            Stream responseStream = null;
            StreamReader reader = null;

            // URI variable.
            Uri requestUri = null;

            // Specify operation to use for the service management call.
            // This sample will use the operation for listing the hosted services.
            string operation = "hostedservices";

            // The ID for the Windows Azure subscription.
            string subscriptionId = "";

            // The thumbprint for the certificate. This certificate would have been
            // previously added as a management certificate within the Windows Azure management portal.
            string thumbPrint = "";

            // Open the certificate store for the current user.
            certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            certStore.Open(OpenFlags.ReadOnly);

            // Find the certificate with the specified thumbprint.
            certCollection = certStore.Certificates.Find(
                                 X509FindType.FindByThumbprint,
                                 thumbPrint,
                                 false);

            // Close the certificate store.
            certStore.Close();

            // Check to see if a matching certificate was found.
            if (0 == certCollection.Count)
            {
                throw new Exception("No certificate found containing thumbprint " + thumbPrint);
            }

            // A matching certificate was found.
            certificate = certCollection[0];
            Console.WriteLine("Using certificate with thumbprint: " + thumbPrint);

            // Create the request.
            requestUri = new Uri("https://management.core.windows.net/"
                                 + subscriptionId 
                                 + "/services/" 
                                 + operation);

            httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(requestUri);

            // Add the certificate to the request.
            httpWebRequest.ClientCertificates.Add(certificate);

            // Specify the version information in the header.
            httpWebRequest.Headers.Add("x-ms-version", "2011-10-01");

            // Make the call using the web request.
            httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

            // Display the web response status code.
            Console.WriteLine("Response status code: " + httpWebResponse.StatusCode);

            // Display the request ID returned by Windows Azure.
             if (null != httpWebResponse.Headers)
             {
                 Console.WriteLine("x-ms-request-id: "
                 + httpWebResponse.Headers["x-ms-request-id"]);
             }

            // Parse the web response.
            responseStream = httpWebResponse.GetResponseStream();
            reader = new StreamReader(responseStream);
            // Display the raw response.
            Console.WriteLine("Response output:");
            Console.WriteLine(reader.ReadToEnd());

            // Close the resources no longer needed.
            httpWebResponse.Close(); 
            responseStream.Close(); 
            reader.Close();
        }
        catch (Exception e)
        {

            Console.WriteLine("Error encountered: " + e.Message);

            // Exit the application with exit code 1.
            Console.ReadLine();
            System.Environment.Exit(1);

        }
        finally
        {
            // Exit the application.
            Console.ReadLine();
            System.Environment.Exit(0);
        }
    }
4

3 に答える 3

7

あなたが提供したazure create certリンクを使用して、同じ問題に遭遇していました。その方法で証明書を作成すると、秘密鍵がクラウド サービスにアップロードされていないことがわかりました。サービスは証明書を見つけることができましたが、リクエストを送信する際にはまだ承認されていませんでした。

次の方法を使用して、秘密鍵と公開鍵の証明書を作成しました。Visual Studio コマンド プロンプトで、ファイルを作成し.cerます.pfx

makecert -r -pe -n "CN=AzureManage" -sky exchange "AzureManage.cer" -sv "AzureManage.pvk"
pvk2pfx -pvk "AzureManage.pvk" -spc "AzureManage.cer" -pfx "AzureManage.pfx" -pi password

最初のコマンドは、秘密鍵と公開鍵のファイルを作成します。パスワードの入力を数回求められます。2 番目のコマンドは、2 つを pfx ファイルに結合します。オフのまま-pi passwordにすると、端末にパスワードを入力する代わりに、パスワードの入力を求められます。

次に、ファイルを適切にインポートします。

  • mmc を使用して、pfx をローカル マシン/個人証明書ストアにインポートします。
  • pfx を Azure クラウド サービスにアップロードします。
  • cer を Azure 管理証明書ストアにアップロードします。
  • pfx の拇印を Azure Role Certificates プロパティに追加します。

次に、Azure 管理 REST API を次のように使用できます。

X509Certificate2 GetCertificate(string thumbprint)
{
  var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
  store.Open(OpenFlags.ReadOnly);
  var certs = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);

  if (certs.Count == 0) return null;
  var cert = certs[0];
  store.Close();
  return cert;
}

HttpWebRequest request = WebRequest.CreateHttp(apiUrl);
request.ClientCertificates.Add(cert);
request.Headers.Add("x-ms-version", "2012-03-01");
于 2013-11-19T17:07:52.013 に答える
1

あなたの問題は次のコード行にあると思います:

certStore = new X509Store(StoreName.My, **StoreLocation.CurrentUser**);

適切にアップロードされた証明書 (管理ポータルを介して適切にアップロードされた .pfx であると仮定) は、CurrentUser ではなく LocalMachine ストアに格納されると予想されます。

また、証明書ストアから証明書を読み取るには、ロールを完全な信頼で実行する必要があります (これは、Visual Studio のロールのプロジェクト プロパティで指定/検証できます)。

于 2013-11-08T03:08:59.893 に答える