azure - 如何使用服务主体在 Angular 中使用 C# 访问 Azure Blob 容器图像
问题描述
除了连接字符串、SAS 令牌和其他方法,我们如何使用“服务主体 (OAuth)”身份验证来实现功能。
服务主体通常提供来自 Azure 的“客户端 ID”、“客户端密码”和“租户 ID”值。
解决方案
解决此问题的步骤如下:
- 生成 OAuth 令牌
- 创建令牌凭据对象。
- 获取 Azure 云容器参考。
- 获取 blob 引用,读取到流并转换为 base 64 字节
- 在 Angular 6+ 页面中显示字节数组图像
命名空间:
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
第 1 步:生成 OAuth 令牌- 使用客户端 ID 和客户端密码,生成访问令牌。我们稍后将使用它进行身份验证。
public string GetUserOAuthToken()
{
const string ResourceId = "https://storage.azure.com/";
const string AuthInstance = "https://login.microsoftonline.com/{0}/";
string authority = string.Format(CultureInfo.InvariantCulture, AuthInstance, ConfigHelper.AzStorAccTenantId);
AuthenticationContext authContext = new AuthenticationContext(authority);
var clientCred = new ClientCredential(ConfigHelper.AzStorAccClientId, ConfigHelper.AzStorAccClientSecret);
AuthenticationResult result = authContext.AcquireTokenAsync(ResourceId, clientCred).Result;
return result.AccessToken;
}
第 2 步:创建令牌凭证对象
public bool GenerateTokenCredentials()
{
if (string.IsNullOrEmpty(authenticationError))
{
string authenticationResult = GetUserOAuthToken();
if (string.IsNullOrEmpty(authenticationResult))
{
return false;
}
else
{
_tokenCredentials = new TokenCredential(authenticationResult);
//_tokenCredentials is a global object
return true;
}
}
else
{
return false;
}
}
步骤 3:获取 Azure 云容器参考
public CloudBlobContainer CreateCloudBlobContainer()
{
try
{
GenerateTokenCredentials();
StorageCredentials storageCredentials = new StorageCredentials(_tokenCredentials);
CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentials, ConfigHelper.AzStorAccName, ConfigHelper.AzStorageEndPoint, useHttps: true);
CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();
return blobClient.GetContainerReference(ConfigHelper.AzStorAccBlobContName);
}
catch (Exception ex)
{
}
return null;
}
第 4 步:获取 blob 引用,读取到流,并转换为 base 64 字节
public async Task<string> DownloadFile(string blobFileName)
{
try
{
CloudBlobContainer blobContainer = CreateCloudBlobContainer();
var blob = blobContainer.GetBlobReference(blobFileName);
blob.FetchAttributes();
var stream = await blob.OpenReadAsync();
var byteData = ReadFully(stream);
string byteImageUrl = string.Format("data:image/{0};base64," + Convert.ToBase64String(byteData), GetBlobImageExtension(blobFileName));
return byteImageUrl;
}
catch (Exception ex)
{
}
return string.Empty;
}
辅助私有方法
private byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
private string GetBlobImageExtension(string blobFileName)
{
string extension = Path.GetExtension(blobFileName).Trim().ToLower().Replace(".", string.Empty);
string formattedExtensionForByteArray = !string.IsNullOrEmpty(extension) ? extension.Equals("svg") ? extension + "+xml" : extension : string.Empty;
return formattedExtensionForByteArray;
}
第 5 步:在 Angular 6+ 中显示字节数组图像
<img [src]="LogoFileName" class="logo" />
- 打字稿
LogoFileName: SafeResourceUrl;
this.LogoFileName = this.sanitizer.bypassSecurityTrustResourceUrl(responseLogoFileName);
这是一个完整的工作示例,用于使用 Azure Blobs 容器映像并在不将它们下载到驱动器的情况下显示它们。
推荐阅读
- javascript - Vanilla JavaScript 切换功能将我的 h2 标签向上移动
- sql - SAS 错误:子查询评估为多于一行 - SQL 查询
- javascript - 根据用户输入多次迭代数组并添加新索引
- google-apps-script - 新的 Google Apps 脚本编辑器 - 其他绑定项目?
- java - 如何将此数字解析为时间戳?
- python - 查找具有相同值的字典并向它们添加新键
- javascript - 在 Kubernetes 上配置 NATS max_payload
- google-apps-script - Google 表格:创建一个下拉菜单,在源代码范围内维护字体格式
- firebase - 将 FCM 从一个 Firebase 帐户发送到使用不同包名称编译的应用
- kubernetes - 带有 flannel 的 Kubernetes 集群 - 端口转发