问题描述
我想使用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
已过时了吗?
注意:
- 我已经在Azure端配置了权限:为此,我创建了一个
app registration
,其中包含一个用于将权限授予contributor
的秘密; -
management.azure.com
API与Bearer令牌一起使用。我可以访问其他资源,例如https://management.azure.com/subscriptions/{subscription-id}/resourcegroups?api-version=2017-05-10
,但是不能访问https://management.core.windows.net/{subscription-id}/services/hostedservices
资源。 - 我正在邮递员上对此进行测试。
解决方案
问题与证书配置有关
$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();
解决方法
根据您的描述,您想要管理Azure云服务。 Azure云服务是Can I use...。因此,我们需要使用Azure服务管理API对其进行管理。如果要调用API,则需要进行X509客户端证书身份验证。有关更多详细信息,请参阅Azure classic resource
详细步骤如下
-
将证书上传到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(订阅->您的订阅->管理证书) document -
代码(例如,我在订阅中列出了云服务)
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));
}