【问题标题】:Error when calling any method on Service Management API调用服务管理 API 上的任何方法时出错
【发布时间】:2016-03-12 20:17:23
【问题描述】:

我希望从将托管在 Azure Web 应用程序上的 c# 应用程序启动 Azure Runbook。

我正在使用证书身份验证(只是为了测试我是否可以连接并检索一些数据)

到目前为止,这是我的代码:

var cert = ConfigurationManager.AppSettings["mgmtCertificate"];

var creds = new Microsoft.Azure.CertificateCloudCredentials("<my-sub-id>",
new X509Certificate2(Convert.FromBase64String(cert)));

var client = new Microsoft.Azure.Management.Automation.AutomationManagementClient(creds, new Uri("https://management.core.windows.net/"));
var content = client.Runbooks.List("<resource-group-id>", "<automation-account-name>");

每次我运行这个,无论我使用什么证书,我都会得到同样的错误:

An unhandled exception of type 'Hyak.Common.CloudException' occurred in Microsoft.Threading.Tasks.dll

Additional information: ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.

我已尝试下载设置文件,其中包含您在启动 Azure 帐户时获得的自动生成的管理证书...我所做的任何事情都不会让我与任何 Azure 订阅者交谈

我在这里遗漏了一些基本的东西吗?

编辑:一些附加信息...

所以我决定创建一个应用程序并使用 JWT 身份验证方法。

我添加了一个应用程序,授予 Azure 服务管理 API 的应用程序权限,并确保用户是共同管理员,但我仍然收到相同的错误,即使使用令牌...

const string tenantId = "xx";
const string clientId = "xx";

var context = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenantId));

var user = "<user>";
var pwd = "<pass>";
var userCred = new UserCredential(user, pwd);

var result = context.AcquireToken("https://management.core.windows.net/", clientId, userCred);

var token = result.CreateAuthorizationHeader().Substring("Bearer ".Length);  // Token comes back fine and I can inspect and see that it's valid for 1 hour - all looks ok...

var sub = "<subscription-id>";
var creds = new TokenCloudCredentials(sub, token);
var client = new AutomationManagementClient(creds, new Uri("https://management.core.windows.net/"));

var content = client.Runbooks.List("<resource-group>", "<automation-id>");

我也尝试过使用其他 Azure 库(如身份验证、数据中心等),但我得到了同样的错误:

ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.

我确定它只是 1 个复选框,我需要在那个单一的管理门户中的某个地方打勾,但我已经遵循了一些关于如何执行此操作的教程,但最终都出现了这个错误......

【问题讨论】:

  • 我一直在使用ClientCredential 而不是UserCredential cloudidentity.com/blog/2014/07/08/…
  • @MilenPavlov 对此表示感谢,但我已经尝试使用本地应用程序和 Web 应用程序,同时使用客户端凭据(使用密钥)和使用用户名/密码的用户凭据。我遇到了同样的问题(我成功获得了一个令牌,它只是不允许我执行任何操作)
  • 我在var content = await client.Runbooks.ListByNameAsync("automationAccount", "runbookName", cancelationToken);上找不到异常
  • @MilenPavlov 你和我有同样的问题吗?
  • 在这里找到它stackoverflow.com/questions/24999518/…,刚刚测试过:)

标签: c# azure azure-automation


【解决方案1】:
    public async Task StartAzureRunbook()
    {
        try
        {
            var subscriptionId = "azure subscription Id";
            string base64cer = "****long string here****"; //taken from http://stackoverflow.com/questions/24999518/azure-api-the-server-failed-to-authenticate-the-request

            var cert = new X509Certificate2(Convert.FromBase64String(base64cer));

            var client = new Microsoft.Azure.Management.Automation.AutomationManagementClient(new CertificateCloudCredentials(subscriptionId, cert));
            var ct = new CancellationToken();

            var content = await client.Runbooks.ListByNameAsync("MyAutomationAccountName", "MyRunbookName", ct);


            var firstOrDefault = content?.Runbooks.FirstOrDefault();
            if (firstOrDefault != null)
            {
                var operation = client.Runbooks.Start("MyAutomationAccountName", new RunbookStartParameters(firstOrDefault.Id));
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }       

也在传送门中: 1) 应用程序是多租户的 2) 对其他应用程序的权限部分 - Windows Azure 服务管理器 - 委派权限“访问 Azure 服务管理(预览版)”

【讨论】:

  • 谢谢,我会试一试,让你知道
  • 您使用的是什么版本的 Azure API?我没有ListByNameAsync,它期望resourcegroupname 作为列表方法的第一个参数..
  • &lt;package id="Microsoft.Azure.Management.Automation" version="0.15.2-preview" targetFramework="net452" /&gt;
  • 啊,对了,拿到预览版后一切正常!真的很烦人,就像 MSDN 上的教程之一说要使用最新的预发布,没想到这会导致这样的问题,但显然就是这样!谢谢:)
  • 也适用于基于令牌的访问方法...该死的整天撞墙!
【解决方案2】:

确保您的管理证书具有私钥并且不是从 .CER 文件生成的。您在生成 X509Certificate 对象时没有提供密码这一事实让我认为您只使用公钥

确保您的 Managemnet 的证书公钥(.CER 文件)已上传到 Azure 管理门户(旧版,管理证书区域)

使用 CertificateCloudCredentials 而不是对象的任何其他凭据类型

【讨论】:

  • 我尝试使用每种凭据类型都没有成功,包括我生成的证书和我生成并传递给 .NET 应用程序的 .pfx。我什至采用了您在创建订阅时获得的默认管理证书并使用了它(我可以在调试中看到我使用的所有证书都显示HasPrivateKey = true)所以我不认为是这个......为什么使用令牌不起作用吗?我读到的所有内容都说 MS 正在逐步淘汰证书身份验证,并且正在转向基于令牌的...为什么我会在那里遇到同样的错误?
  • 答案在于证书。不要打扰其他类型的凭据。这一行 new X509Certificate2(Convert.FromBase64String(cert)) 告诉我证书是由公钥制成的。配置文件中的“cert”字符串是什么?私钥需要解密密码
  • 是的,我也尝试过 - 我按照指示将证书上传到 Azure。我从证书创建了一个 pfx 并使用了需要密码的新 X509Certificate2 的重载(我什至故意尝试输入错误的密码以确保在这种情况下存在不同的行为。NET 抛出无效密码异常)。我已经完成了所有身份验证方法的每一个演练,它们都最终导致了这个错误......
  • 例如new Microsoft.Azure.CertificateCloudCredentials(sub, new X509Certificate2(@"path-to-cert.pfx", "&lt;password&gt;")) - 使用已在 Azure 门户上作为管理证书应用的凭据仍然失败
  • 很抱歉继续怀疑,但多年来支持 AzureWatch 和 CloudMonix,我看到客户经常将证书上传到错误的区域或错误的订阅。您能否仔细检查门户中的正确子是否具有正确的 mgmt 证书?
【解决方案3】:

好的,确实很愚蠢,但我遵循的教程之一建议安装库的预发布版本。

安装预览版(0.15.2-preview)已经解决了这个问题!

【讨论】:

    猜你喜欢
    • 2019-03-01
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    相关资源
    最近更新 更多