从Azure Keyvault获取X509证书以在REST调用中使用

问题描述 投票:0回答:2

我正在尝试从Azure Keyvault获得证书,然后使用它来调用需要证书进行身份验证的REST API。

我尝试在本地执行此操作-我在磁盘上有.pfx文件,将其加载到字节数组中,然后从中创建证书:

X509Certificate2 x509 = new X509Certificate2(File.ReadAllBytes(path), password);

然后在RestSharp中使用该证书进行我的REST调用:

IRestClient client = new RestClient(url);
client.ClientCertificates = new X509CertificateCollection { x509 };

var request = new RestRequest(lastUrlPart, Method.GET);
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/json");

IRestResponse response = client.Execute(request);

if (response.IsSuccessful)
{
    // read out the response and process it
}

像魅力一样工作。

现在,我尝试执行相同的操作,但是要从Azure Keyvault获取证书。我已经在Azure AD中创建了一个应用程序注册,创建了我的密钥库,并为我的应用程序注册的服务身份提供了对该密钥库的访问权限。我已将证书上传到密钥库中。到目前为止,一切都很好。

我发现此代码可从Keyvault提取证书:

var azureServiceTokenProvider = new AzureServiceTokenProvider();

var kv = new KeyVaultClient(async (authority, resource, scope) =>
                                        {
                                            var authContext = new AuthenticationContext(authority, TokenCache.DefaultShared);
                                            var clientCred = new ClientCredential(clientAppId, clientSecret);
                                            var result = await authContext.AcquireTokenAsync(resource, clientCred);

                                            if (result == null)
                                            {
                                                throw new InvalidOperationException("Failed to obtain the JWT token");
                                            }

                                            return result.AccessToken;
                                        });

string certIdentifier = "https://mykeyvault.vault.azure.net/certificates/Certificate-TEST/14753af7586445fe9d57efa136ac090c";

var vaultCertificate = kv.GetCertificateAsync(certIdentifier).GetAwaiter().GetResult();

[这也可行-我可以使用我的应用程序身份访问密钥仓库,并且可以从密钥仓库获取证书,并且X.509指纹有效-但这现在是CertificateBundle名称空间中的Microsoft.Azure.KeyVault.Models-如何将其“转换”为“常规” X509Certificate2对象,以便可以将其用于REST调用?

例如,我尝试过几件事

X509Certificate2 x509 = new X509Certificate2(vaultCertificate.Cer);

但没有任何效果-当我发起REST调用时,我收到HTTP 403-禁止错误返回...。

我想念什么?如何从Azure Keyvault中获取可用于在后续REST调用中进行身份验证的格式的证书?

rest x509certificate azure-keyvault
2个回答
1
投票

当然-在发布此问题后,我偶然发现了解决方案...。

blog post by Matt Small对其进行了详尽的解释(并提供了非常不错的[代码示例)。

基本上,为了使用证书进行身份验证,您也需要具有私钥-并且当您执行GetCertificateAsync时,您只获取证书的公共信息。

您需要获取证书

作为秘密,然后对base64进行解码-然后,您将获得所有必需的位,并且REST调用起作用。

哎呀!为什么这真是令人费解?为什么在includePrivate: bool调用中不能仅存在一个GetCertificateAsync参数来告诉Keyvault,您是否只需要证书的公共部分或公共

私有部分? 您存储证书-但是要获取证书,您需要获取一个秘密....那完全是错误的,并且违反了

[最不惊讶的基本原理!

] MS,如果您正在监听-此API确实需要做更多的工作才能使新手Azure开发人员更易于使用!和PS:当然,这也意味着您用来访问密钥库的用户/身份现在需要

权限

来读取机密-不仅仅是证书.....

0
投票
尝试以下代码:

var cert = kvc.GetCertificateAsync(baseUrl, "Demo").ConfigureAwait(false).GetAwaiter().GetResult(); var cert_content = cert.Cer; X509Certificate2 x509 = new X509Certificate2(cert_content);

您可以轻松地从CertificateBundle获取证书的原始字节,然后使用原始字节创建X509Certificate2实例。 
© www.soinside.com 2019 - 2024. All rights reserved.