我们目前正在 ASP NET MVC 4 (C#) 和 Angularjs 中开发一个 Web 应用程序,其中我们生成的内容被加密并保存在 Windows Azure 上。
有时,IIS 会随机挂起请求,并且它们仍处于 ExecuteRequestHandler 阶段。一旦发生这种情况,所有后续请求都将挂起,并且我们的 IIS 日志中找不到任何错误。
我们使用 Microsoft.WindowsAzure SDK 处理 Windows Azure 的所有内容,并使用下载/上传操作期间为 blob 提供的加密策略(EncryptionPolicy 属性)对所有 blob 进行加密。我们还将加密 key 保存在 Windows Azure 上的 key 保管库中。
以下是检索我们的政策的代码:
public async static Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
var credentials = new ClientCredential(AzureSection.ClientId, AzureSection.ClientSecret);
var result = await authContext.AcquireTokenAsync(resource, credentials);
if(result == null)
throw new InvalidOperationException("Error when obtaining KeyVault token");
return result.AccessToken;
}
public static BlobEncryptionPolicy GetUploadPolicy()
{
if (_policyUpload == null && !IsDebug)
{
var resolver = new KeyVaultKeyResolver(KeyVaultHelper.GetToken);
var key = resolver.ResolveKeyAsync(AzureSection.ResourceGroup.KeyVault.Url, CancellationToken.None).GetAwaiter().GetResult();
_policyUpload = new BlobEncryptionPolicy(key, null);
}
return _policyUpload;
}
public static BlobEncryptionPolicy GetDownloadPolicy()
{
if (_policyDownload == null && !IsDebug)
{
var resolver = new KeyVaultKeyResolver(KeyVaultHelper.GetToken);
_policyDownload = new BlobEncryptionPolicy(null, resolver);
}
return _policyDownload;
}
以及我们如何在下载/上传操作期间使用它:
_policyDownload = PolicyHelper.GetDownloadPolicy();
public Task DownloadToStreamAsync(Stream output)
{
return !BaseBlob.Exists() ? null
: BaseBlob.DownloadToStreamAsync(output, null, new BlobRequestOptions{
DisableContentMD5Validation = true,
EncryptionPolicy = _policyDownload
}, null);
}
其中 BaseBlob 是 Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob,AzureSection 是 web.config 中的一个部分。
我们的服务器是在 Windows Server 2008 R2 上运行的 IIS 7.5。 我们在 Windows Server 2012 和 IIS 8 上尝试过,但出现同样的问题。
当我们从 blob 操作中删除 EncryptionPolicy 时,一切正常。
有谁知道为什么会发生这种情况,因为我找不到任何东西(因为最近实现了 azure 加密,并且挂起的请求不会向我们提供任何错误)?
编辑
我尝试使用它来检索我们的加密策略(如 https://azure.microsoft.com/en-us/documentation/articles/storage-encrypt-decrypt-blobs-key-vault/ 的评论中建议的那样):
using Microsoft.Azure.KeyVault.WebKey;
var kv = new KeyVaultClient(Utils.GetToken);
var key = kv.GetKeyAsync("https://contosokeyvault.vault....").Result;
var rsa = new RsaKey(key.KeyIdentifier.Identifier, key.Key.ToRSA());
但仍然是同样的问题。
编辑2
我也尝试不使用静态属性来保留我们的上传和下载策略,但仍然存在同样的问题。
最佳答案
知道这有点老了,但我们最近遇到了这个问题并设法解决了它。该问题是由异步方法中创建的死锁引起的。
最后综合了这里提出的建议https://stackoverflow.com/a/32429753/3391469在这里 https://stackoverflow.com/a/27581462/3391469成功了。
blockBlob.DownloadToStream(stream, null, Task.Run(() => GetOptions()).Result);
private async static Task<BlobRequestOptions> GetOptions()
{
var cloudResolver = new KeyVaultKeyResolver(GetToken);
var rsa = await cloudResolver.ResolveKeyAsync(Config.Get("AzureKeyVault"), CancellationToken.None).ConfigureAwait(false);
var policy = new BlobEncryptionPolicy(rsa, null);
return new BlobRequestOptions() { EncryptionPolicy = policy };
}
关于c# - IIS 因 Windows Azure 存储加密而随机挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33484769/