[英]Not able to use blob storage operations using System Assigned Managed Identity in Azure
Getting "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature."获取“服务器无法验证请求。确保授权 header 的值正确形成,包括签名。” error while trying to use System Assigned Managed Identity in Azure using C# language.
尝试使用 C# 语言在 Azure 中使用系统分配的托管标识时出错。
The steps followed遵循的步骤
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
at Microsoft.Azure.Storage.Core.Executor.Executor.<ExecuteAsync>d__1`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Storage.Blob.CloudBlockBlob.<DownloadTextAsync>d__72.MoveNext()
The Program Class程序 Class
class Program
{
static void Main(string[] args)
{
try
{
var blob = new AzureCloudBlob();
Console.WriteLine(blob.ReadBlob());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
}
The AzureCloudBlob class, used to connect and read a blob using System Assigned Managed Idenitity access token AzureCloudBlob class,用于使用系统分配的托管身份访问令牌连接和读取 blob
class AzureCloudBlob
{
public CloudBlockBlob CreateConnection()
{
var token = GetToken();
var tokenCredentials = new TokenCredential(token);
var storageCredentials = new StorageCredentials(tokenCredentials);
var serviceUri = new Uri("https://mystorageacc.blob.core.windows.net/practice/blob.txt");
return new CloudBlockBlob(serviceUri, storageCredentials);
}
public string ReadBlob()
{
var client = CreateConnection();
var blobClient = client.DownloadTextAsync();
var data = blobClient.Result;
return data;
}
public string GetToken()
{
var request = (HttpWebRequest)WebRequest.Create("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/");
request.Headers["Metadata"] = "true";
request.Method = "GET";
try
{
var response = (HttpWebResponse)request.GetResponse();
var streamResponse = new StreamReader(response.GetResponseStream());
string stringResponse = streamResponse.ReadToEnd();
var list = (Dictionary<string, string>)JsonConvert.DeserializeObject(stringResponse, typeof(Dictionary<string, string>));
string accessToken = list["access_token"];
Console.WriteLine(accessToken);
return accessToken;
}
catch (Exception e)
{
string errorText = String.Format("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : "Acquire token failed");
Console.WriteLine(errorText);
return errorText;
}
}
}
If you want to access Azure storage with Azure AD auth, we should use resouce=https://storage.azure.com/
to get Azure AD access token. If you want to access Azure storage with Azure AD auth, we should use resouce
resouce=https://storage.azure.com/
to get Azure AD access token. But you use resource=https://management.azure.com/
.但是您使用
resource=https://management.azure.com/
。 Please replace it.请更换它。 Besides, please note that you need to assign right role to the MSI.
此外,请注意您需要为 MSI 分配正确的角色。 The role should be Storage Blob Data Reader , Storage Blob Data Contributor or Storage Blob Data Owner .
角色应该是Storage Blob Data Reader 、 Storage Blob Data Contributor或Storage Blob Data Owner 。
The detailed steps are as below详细步骤如下
Enable system-assigned managed identity on Azure VM在 Azure VM 上启用系统分配的托管标识
$vm = Get-AzVM -ResourceGroupName myResourceGroup -Name myVM Update-AzVM -ResourceGroupName myResourceGroup -VM $vm -AssignIdentity:$SystemAssigned
Assign role to MSI on storage account scope将角色分配给存储帐户 scope 上的 MSI
$sp =Get-AzADServicePrincipal -displayname "<your VM name>" New-AzRoleAssignment -ObjectId $sp.id ` -RoleDefinitionName "Storage Blob Data Reader" ` -Scope "/subscriptions/<subscription>/resourceGroups/sample-resource-group/providers/Microsoft.Storage/storageAccounts/<storage-account>"
code代码
class Program { static void Main(string[] args) { //get token string accessToken = GetMSIToken("https://storage.azure.com/"); //create token credential TokenCredential tokenCredential = new TokenCredential(accessToken); //create storage credentials StorageCredentials storageCredentials = new StorageCredentials(tokenCredential); Uri blobAddress = new Uri("<URI to blob file>"); //create block blob using storage credentials CloudBlockBlob blob = new CloudBlockBlob(blobAddress, storageCredentials); //retrieve blob contents Console.WriteLine(blob.DownloadText()); Console.ReadLine(); } static string GetMSIToken(string resourceID) { string accessToken = string.Empty; // Build request to acquire MSI token HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=" + resourceID); request.Headers["Metadata"] = "true"; request.Method = "GET"; try { // Call /token endpoint HttpWebResponse response = (HttpWebResponse)request.GetResponse(); // Pipe response Stream to a StreamReader, and extract access token StreamReader streamResponse = new StreamReader(response.GetResponseStream()); string stringResponse = streamResponse.ReadToEnd(); JavaScriptSerializer j = new JavaScriptSerializer(); Dictionary<string, string> list = (Dictionary<string, string>)j.Deserialize(stringResponse, typeof(Dictionary<string, string>)); accessToken = list["access_token"]; return accessToken; } catch (Exception e) { string errorText = String.Format("{0} \n\n{1}", e.Message, e.InnerException?= null. e.InnerException:Message; "Acquire token failed"); return accessToken; } } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.