简体   繁体   中英

Azure API The server failed to authenticate the request

I have a task ( I tried with worker role and to upload a console app and run the .exe) that should run once a day and gather Azure Metrics of some of my VMs. This works flawlessly locally but on a cloud service I get this Error:

Unhandled Exception: Microsoft.WindowsAzure.CloudException: ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and associated with this subscription. at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSucces ... etc.

The line where this happens is:

MetricDefinitionListResponse metricListResponse = metricsClient.MetricDefinitions.List(resourceId, null,
            nspace);

This is part of my code:

 string subscriptionId = "fc4xxxx5-835c-xxxx-xxx-xxxxxxx";

        // The thumbprint of the certificate.
        string thumbprint = "‎f5 b4 xxxxxxxx f7 c2";

        // Get the certificate from the local store.
        //X509Certificate2 cert = GetCertificate(StoreName.My, StoreLocation.LocalMachine, thumbprint);
        //cert = GetCertificate(StoreName.My, StoreLocation.CurrentUser, thumbprint) ?? new X509Certificate2(("manageAzure.cer"));
        var cert = new X509Certificate2(("manageAzure.cer"));

        Console.WriteLine("Certificate is : " + cert);

        // Create the metrics client.
        var metricsClient = new MetricsClient(new CertificateCloudCredentials(subscriptionId, cert));

        Console.WriteLine("metricsClient is : " + metricsClient);

        // The cloud service name and deployment name, found in the dashboard of the management portal.
        string cloudServiceName = "abms2-carlsberg";
        string deploymentName = "abms2-carlsberg";

        // Build the resource ID string.
        string resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId(cloudServiceName, deploymentName);

        string nspace = "WindowsAzure.Availability";

        // Get the metric definitions.
        MetricDefinitionListResponse metricListResponse = metricsClient.MetricDefinitions.List(resourceId, null,
            nspace);

I have placed the management certificate in my solution, and I load it from there (it is set to always copy) and is the same (and the same way) I use when I run it locally.

So what "certificate" is it complaining about "to authenticate"? I can't seem to see what the problem is. Any help would be greatly appreciated as I have used the whole afternoon on this!

PS: I am already running this in elevated mode!

For someone else that may have this issue, I have solved it as explained here in the bottom : ( http://www.dinohy.com/post/2013/11/12/403-Forbidden-when-Use-Azure-Management-REST-API-on-Role-instance.aspx )

  1. Download the publishsettings file from: https://manage.windowsazure.com/publishsettings/index?client=vs&schemaversion=2.0 (This is a XML file, you can open it with notepad)

  2. Find ManagementCertificate property, copy the value to a string. That a Base64 encoded string, you can use this string create a certificate: string base64Cer="The value of ManagementCertificate "

  3. Use this string create a certificate. var certificate = new X509Certificate2(base64Cer);

although this last step is not exactly like passing the string directly (as the string is too long and will cause an exception) but rather is as follows: var cert = new X509Certificate2(Convert.FromBase64String(base64cer));

Hope this will help someone else in my position too.

At a guess... You are loading the certificate you use to authenticate yourself from a .cer file. That doesn't have the private key so can't be used to authenticate you. I suspect that locally you probably have the private key stored in your private certificate store, assuming you generated the cert on your machine, which would probably make it work locally.

In short, try using a pfx file instead of a cer. The pfx for has the private key in it. If you generated the cert on your machine with makecert you will initially only have the .cer file. Use the local certificate manager to find the certificate in your personal store, then export it to a pfx file and include the private key.

This method helped me...

        public static X509Certificate2 GetCertificate(string certificateString)
        {
            if (string.IsNullOrEmpty(certificateString))
                return null;
            var certificateAsBytes = Convert.FromBase64String(certificateString);
            var certificate = new X509Certificate2(certificateAsBytes);
            return certificate;
        }

Also i came up with another scenario. Error occurs when your subscription id's mismatch.

Certificate:

<Subscription
      ServiceManagementUrl="https://management.core.windows.net"
      Id="00000000-0000-0000-0000-000000000000" /* -- Subscription Id -- */ 
      Name="Visual Studio Premium with MSDN"
      ManagementCertificate="" />

I'm trying to get credentials like this

Code:

string subscriptionId = "11111111-1111-1111-1111-111111111111"; // Subscription Id...
var credentials = new CertificateCloudCredentials(subscriptionId, x509Certificate2); // Will be varied here...

Where as my subscription id are mismatched. So, received this exception when i try to authenticate my request using "Certificates."

Hope this helps...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM