首页 > 解决方案 > 为什么我使用 Azure 服务管理 API 得到 403?

问题描述

我想使用 Azure API 管理 ( management.core.windows.net) 重新启动角色实例(参考 Microsoft 文档:https ://docs.microsoft.com/en-us/rest/api/compute/cloudservices/rest-reboot-role-instance )但我收到了 403 作为回应。

要求:

https://management.core.windows.net/{subscription-id}/services/hostedservices/{hosted-service}/deploymentslots/staging/roleinstances/{role-instance-name}?comp=reboot`

Headers:
- Authorization: Bearer {token}
- Content-Type: application/xml
- x-ms-version: 2010-10-28
- Content-Length: 0

Body: Empty

响应正文:

<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Code>ForbiddenError</Code>
    <Message>The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.</Message>
</Error>

我通过调用(参考 Microsoft 文档:https ://docs.microsoft.com/en-us/azure/active-directory/azuread-dev/v1-oauth2-client-creds-grant-flow #service-to-service-access-token-request):

https://login.microsoftonline.com/{tenant_id}/oauth2/token

Headers:
- Content-Type: application/x-www-form-urlencoded

Body: 
- grant_type: client_credentials,
- client_id: {client_id}
- client_secret: {client_secret}
- resource: https://management.core.windows.net/

任何想法?请求或 Azure 门户端是否缺少任何配置?是否management.core.windows.net已弃用,因为我可以使用management.azure.com

笔记:


解决方案

问题与证书配置有关

$cert = New-SelfSignedCertificate -Subject "CN=Azure Management API" -CertStoreLocation "cert:\LocalMachine\My" -KeyLength 2048 -KeySpec "KeyExchange" -NotAfter (Get-Date).AddMonths(360)
$password = ConvertTo-SecureString -String "strong-password-here" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath ".\azure-management-api.pfx" -Password $password
Export-Certificate -Type CERT -Cert $cert -FilePath .\azure-management-api.cer

注意证书的重要性.pfx

代码

   var cert = new X509Certificate2( File.ReadAllBytes( "your-certificate-path.pfx" ), "your_password" );
            var httpClientHandler = new HttpClientHandler
            {
                UseProxy = false,
                ClientCertificateOptions = ClientCertificateOption.Manual
            };
            httpClientHandler.ClientCertificates.Add( cert );
            var httpClient = new HttpClient( httpClientHandler );
            httpClient.DefaultRequestHeaders.Add( "Accept", "application/xml" );
            httpClient.DefaultRequestHeaders.Add( "Host", "management.core.windows.net" );
            httpClient.DefaultRequestHeaders.Add( "x-ms-version", "2010-10-28" );
            var uri = $"https://management.core.windows.net/{subscriptionId}/services/hostedservices";
            Console.WriteLine( $"GET {uri} [{httpClient.DefaultRequestVersion}]" );
            foreach ( var header in httpClient.DefaultRequestHeaders )
            {
                Console.WriteLine( $"{header.Key} {header.Value.First()}" );
            }
            var response = httpClient.GetAsync( uri )
                .GetAwaiter()
                .GetResult();
            var content = response.Content.ReadAsStringAsync()
                .GetAwaiter()
                .GetResult();
            Console.WriteLine( $"{(int)response.StatusCode} {response.StatusCode}" );
            Console.WriteLine( content );
            httpClient.Dispose();
            httpClientHandler.Dispose();

标签: azureazure-api-management

解决方案


根据您的描述,您要管理 Azure 云服务。Azure 云服务是Azure 经典资源。所以我们需要使用 Azure 服务管理 API 来管理它。如果我们要调用API,我们需要做X509客户端证书认证。更多详细信息,请参阅文档

详细步骤如下

  1. 将证书上传到 Azure 创建证书

    $cert = New-SelfSignedCertificate -DnsName yourdomain.cloudapp.net -CertStoreLocation "cert:\LocalMachine\My" -KeyLength 2048 -KeySpec "KeyExchange"
    $password = ConvertTo-SecureString -String "your-password" -Force -AsPlainText
    Export-PfxCertificate -Cert $cert -FilePath ".\my-cert-file.pfx" -Password $password
    Export-Certificate -Type CERT -Cert $cert -FilePath .\my-cert-file.cer
    

    b 将.cer文件上传到 Azure(订阅 -> 您的订阅 -> 管理证书) 在此处输入图像描述

  2. 代码(例如,我在订阅中列出了云服务)

 static async Task Main(string[] args)
 {
   var _clientHandler = new HttpClientHandler();
                _clientHandler.ClientCertificates.Add(GetStoreCertificate("the cert's thumbprint" ));
                _clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
                String uri = string.Format("https://management.core.windows.net/{0}/services/hostedservices", "subscription id");
                using (var _client = new HttpClient(_clientHandler))
                using (var request = new HttpRequestMessage(HttpMethod.Get, uri)) {
  
                    request.Headers.Add("x-ms-version", "2014-05-01");
                    request.Headers.Add("Accept", "application/xml");
                    //request.Headers.Add("Content-Type", "application/xml");
                    using (HttpResponseMessage httpResponseMessage = await _client.SendAsync(request)) {
                        string xmlString = await httpResponseMessage.Content.ReadAsStringAsync();
                        Console.WriteLine(httpResponseMessage.StatusCode);
                        Console.WriteLine(xmlString);
                    }

                }
}
private static X509Certificate2 GetStoreCertificate(string thumbprint)
        {


            X509Store store = new X509Store("My", StoreLocation.LocalMachine);
            try
            {
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                X509Certificate2Collection certificates = store.Certificates.Find(
                  X509FindType.FindByThumbprint, thumbprint, false);
                if (certificates.Count == 1)
                {
                    return certificates[0];
                }
            }
            finally
            {
                store.Close();
            }

            throw new ArgumentException(string.Format(
              "A Certificate with Thumbprint '{0}' could not be located.",
              thumbprint));
        }

在此处输入图像描述


推荐阅读