Azure API 服务器未能对请求进行身份验证

Posted

技术标签:

【中文标题】Azure API 服务器未能对请求进行身份验证【英文标题】:Azure API The server failed to authenticate the request 【发布时间】:2014-09-19 21:25:50 【问题描述】:

我有一个任务(我尝试使用辅助角色并上传控制台应用程序并运行 .exe),该任务应该每天运行一次并收集我的一些 VM 的 Azure 指标。这在本地完美运行,但在云服务上我收到此错误:

未处理的异常:Microsoft.WindowsAzure.CloudException:ForbiddenError:服务器未能对请求进行身份验证。验证证书是否有效并与此订阅相关联。在 Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSucces ...等。

发生这种情况的行是:

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

这是我的代码的一部分:

 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);

我已将管理证书放在我的解决方案中,并从那里加载它(它设置为始终复制),并且与我在本地运行它时使用的相同(和相同的方式)。

那么它在抱怨“认证”是什么“证书”?我似乎看不出问题出在哪里。任何帮助将不胜感激,因为我已经用了整个下午!

PS:我已经在提升模式下运行它了!

【问题讨论】:

【参考方案1】:

猜测...您正在加载用于从 .cer 文件验证自己的证书。那没有私钥,因此不能用于对您进行身份验证。我怀疑在本地您可能将私钥存储在您的私有证书存储中,假设您在您的机器上生成了证书,这可能会使其在本地工作。

简而言之,尝试使用 pfx 文件而不是 cer。 pfx for 里面有私钥。如果您使用 makecert 在您的机器上生成证书,您最初将只有 .cer 文件。使用本地证书管理器在您的个人存储中查找证书,然后将其导出到 pfx 文件并包含私钥。

【讨论】:

这是我的问题,我更改了代码以检查证书 HasPrivatekey 属性,如果为 false,则失败并出现更有意义的错误。【参考方案2】:

对于可能遇到此问题的其他人,我已按照底部的说明解决了它:(http://www.dinohy.com/post/2013/11/12/403-Forbidden-when-Use-Azure-Management-REST-API-on-Role-instance.aspx)

    从https://manage.windowsazure.com/publishsettings/index?client=vs&schemaversion=2.0下载publishsettings文件(这是一个XML文件,可以用记事本打开)

    找到 ManagementCertificate 属性,将值复制到字符串。那一个Base64编码的字符串,可以用这个字符串创建证书:string base64Cer="The value of ManagementCertificate"

    使用此字符串创建证书。 var 证书 = 新 X509Certificate2(base64Cer);

虽然这最后一步并不完全像直接传递字符串(因为字符串太长会导致异常)而是如下: var cert = new X509Certificate2(Convert.FromBase64String(base64cer));

希望这也能帮助到我这个职位的其他人。

【讨论】:

此错误消息='尝试创建计划作业'作业名称'失败,并显示以下消息:'系统找不到指定的文件。 '.'.......所以它不是一个正确的答案【参考方案3】:

这个方法帮了我...

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

我还想出了另一个场景。 当您的订阅 ID 不匹配时会发生错误。

证书:

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

我正在尝试获取这样的凭据

代码:

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

我的订阅 ID 不匹配。因此,当我尝试使用“证书”验证我的请求时收到此异常。

希望这会有所帮助...

【讨论】:

以上是关于Azure API 服务器未能对请求进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

AzureStorage:服务器未能对请求进行身份验证。确保 Authorization 标头的值正确形成,包括签名

如何对 Azure 时间序列洞察查询 API 进行身份验证?

使用 Azure AD 通过 OAuth2 对 Azure API 管理进行身份验证

对 C# 中的每个请求强制进行 Azure 重新身份验证

Azure 存储 SAS 无法进行身份验证

无法对 Azure 上的 API 管理执行资源所有者密码 OAuth2 身份验证