从 Azure API 管理调用时 X-ARR-ClientCert header 中没有证书
No certificate in X-ARR-ClientCert header when called from Azure API Management
我已经配置了一个 Azure 网站(有一个 ApiController) to use client-certificate authentication using the instructions provided here。总结:您将 clientCertEnabled
标志设置为 true
,然后您的网站开始请求 client-authentication-certificate.
效果很好,但是,现在我想访问发送到服务器的客户端证书。根据 MSDN 文章,它应该在 X-ARR-ClientCert
请求 header 中可用,但它不是!!
这意味着 任何人 拥有 client-authentication-certificate 都可以访问我的 API,这对我来说是不可取的。
那么如何检索客户端发送到我的 Web API 的 client-authentication-certificate?
更新 1:我实际上是通过 Azure API Management 呼叫我的 API。我用我的 client-authentication-certificate 配置了 APIM,并且 APIM 毫无问题地调用了我的 API。但是,当从 APIM 调用 API 时,不会设置 X-ARR-ClientCert header。当通过 Fiddler 直接调用时,我确实看到了 header。所以 APIM 以某种不同的方式调用我的 API?!?
更新 2:我再次检查了所有内容并生成了一些日志记录。首先是 DelegatingHandler
class 的相关部分,我登录自:
protected override async Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Trace.TraceInformation("Going to validate client certificate.");
var x509Certificate2 = request.GetClientCertificate();
Trace.TraceInformation("Client cert: {0}", x509Certificate2 == null
? "<null>"
: x509Certificate2.Subject);
try
{
var headerKeys = string.Join("|", request.Headers.Select(h => h.Key));
Trace.TraceInformation("Header keys: {0}", headerKeys);
...
以及由此产生的日志输出:
2015-12-07T08:08:24 PID[8464] Information Going to validate client certificate.
2015-12-07T08:08:24 PID[8464] Information Client cert: <null>
2015-12-07T08:08:24 PID[8464] Information Header keys:
Connection|Host|Max-Forwards|Conf-Organisation-Key|Ocp-Apim-Subscription-Key|
X-Forwarded-For|X-LiveUpgrade|X-ARR-LOG-ID|DISGUISED-HOST|X-SITE-DEPLOYMENT-ID|
X-Original-URL
所以没有客户端证书,也没有 X-ARR-ClientCert
header.
更新 3:这是当我直接使用 client-authentication-certificate:
进入实际 API 时生成的日志
2015-12-07T09:16:45 PID[8464] Information Going to validate client certificate.
2015-12-07T09:16:45 PID[8464] Information Client cert: CN=rwildenberg@itq.nl
2015-12-07T09:16:45 PID[8464] Information Header keys:
Connection|Accept|Accept-Encoding|Accept-Language|Cookie|Host|Max-Forwards|
User-Agent|Upgrade-Insecure-Requests|DNT|X-LiveUpgrade|X-ARR-LOG-ID|DISGUISED-HOST|
X-SITE-DEPLOYMENT-ID|X-Original-URL|X-Forwarded-For|X-ARR-SSL|X-ARR-ClientCert
直接来自请求的客户端证书和预期的 X-ARR-ClientCert
header.
UPDATE 4:最后这恰好是我自己的错误(当然)。我确信后端的 url 是 https
,而实际上它是 http
。客户端证书身份验证仅适用于 https,因此事后看来,在后端未找到证书是完全合理的...
我正在联系 APIM 中的工程师,以弄清楚这是如何工作的,然后会回复您。当您在实际 API(网络应用程序)前面有 APIM 时,我的猜测是 APIM 是将为您处理所有 authN / authZ 的代理。因此,只有在成功时,请求才会发送到您的 API。我猜这就是为什么他们可能只是丢弃客户端证书而不是转发它。但我完全可以理解为什么客户端证书在网络应用程序中仍然有用。
您真的要为 API 的所有用户管理客户端证书吗?我了解使用客户端证书来确保只有 APIM 可以直接与您的后端 API 对话。通常通过 API 管理公开 API 的开发人员使用 API 密钥来控制对 API 的访问。使用此方法可以根据不同的配置 "products".
应用策略
如果您拥有管理证书创建和吊销的基础架构,那么这可能是正确的选择,这只是一种不常见的方法。话虽如此,我将调查 API 管理中可用的选项,以便能够在 APIM 网关上提取证书指纹。
您还需要为托管的 Azure API 启用客户端证书身份验证 - 此步骤将确保 Azure 携带传入请求中的任何 X-ARR-ClientCert header。
否则,Azure 会在 Request.Headers 到达您的 API.
之前将其从 Request.Headers 中移除
注意:此设置仅适用于付费订阅
- 转到 https://resources.azure.com/ 和 select 您想要的 Azure 帐户
- Select 订阅 -> 资源组 -> your_resource_group -> 提供商 -> microsoft.web -> 站点 -> your_website
- 从顶部按钮进入 Read/Write 模式,进入编辑模式,然后在属性下设置 属性 "clientCertEnabled": true。
"properties": {
"name": "my-site",
"state": "Running",
"hostNames": [
"my-site.azurewebsites.net",
"(string)"
],
...
"clientCertEnabled": true,
...
}
文档:https://docs.microsoft.com/en-us/azure/app-service-web/app-service-web-configure-tls-mutual-auth
我已经配置了一个 Azure 网站(有一个 ApiController) to use client-certificate authentication using the instructions provided here。总结:您将 clientCertEnabled
标志设置为 true
,然后您的网站开始请求 client-authentication-certificate.
效果很好,但是,现在我想访问发送到服务器的客户端证书。根据 MSDN 文章,它应该在 X-ARR-ClientCert
请求 header 中可用,但它不是!!
这意味着 任何人 拥有 client-authentication-certificate 都可以访问我的 API,这对我来说是不可取的。
那么如何检索客户端发送到我的 Web API 的 client-authentication-certificate?
更新 1:我实际上是通过 Azure API Management 呼叫我的 API。我用我的 client-authentication-certificate 配置了 APIM,并且 APIM 毫无问题地调用了我的 API。但是,当从 APIM 调用 API 时,不会设置 X-ARR-ClientCert header。当通过 Fiddler 直接调用时,我确实看到了 header。所以 APIM 以某种不同的方式调用我的 API?!?
更新 2:我再次检查了所有内容并生成了一些日志记录。首先是 DelegatingHandler
class 的相关部分,我登录自:
protected override async Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Trace.TraceInformation("Going to validate client certificate.");
var x509Certificate2 = request.GetClientCertificate();
Trace.TraceInformation("Client cert: {0}", x509Certificate2 == null
? "<null>"
: x509Certificate2.Subject);
try
{
var headerKeys = string.Join("|", request.Headers.Select(h => h.Key));
Trace.TraceInformation("Header keys: {0}", headerKeys);
...
以及由此产生的日志输出:
2015-12-07T08:08:24 PID[8464] Information Going to validate client certificate.
2015-12-07T08:08:24 PID[8464] Information Client cert: <null>
2015-12-07T08:08:24 PID[8464] Information Header keys:
Connection|Host|Max-Forwards|Conf-Organisation-Key|Ocp-Apim-Subscription-Key|
X-Forwarded-For|X-LiveUpgrade|X-ARR-LOG-ID|DISGUISED-HOST|X-SITE-DEPLOYMENT-ID|
X-Original-URL
所以没有客户端证书,也没有 X-ARR-ClientCert
header.
更新 3:这是当我直接使用 client-authentication-certificate:
进入实际 API 时生成的日志2015-12-07T09:16:45 PID[8464] Information Going to validate client certificate.
2015-12-07T09:16:45 PID[8464] Information Client cert: CN=rwildenberg@itq.nl
2015-12-07T09:16:45 PID[8464] Information Header keys:
Connection|Accept|Accept-Encoding|Accept-Language|Cookie|Host|Max-Forwards|
User-Agent|Upgrade-Insecure-Requests|DNT|X-LiveUpgrade|X-ARR-LOG-ID|DISGUISED-HOST|
X-SITE-DEPLOYMENT-ID|X-Original-URL|X-Forwarded-For|X-ARR-SSL|X-ARR-ClientCert
直接来自请求的客户端证书和预期的 X-ARR-ClientCert
header.
UPDATE 4:最后这恰好是我自己的错误(当然)。我确信后端的 url 是 https
,而实际上它是 http
。客户端证书身份验证仅适用于 https,因此事后看来,在后端未找到证书是完全合理的...
我正在联系 APIM 中的工程师,以弄清楚这是如何工作的,然后会回复您。当您在实际 API(网络应用程序)前面有 APIM 时,我的猜测是 APIM 是将为您处理所有 authN / authZ 的代理。因此,只有在成功时,请求才会发送到您的 API。我猜这就是为什么他们可能只是丢弃客户端证书而不是转发它。但我完全可以理解为什么客户端证书在网络应用程序中仍然有用。
您真的要为 API 的所有用户管理客户端证书吗?我了解使用客户端证书来确保只有 APIM 可以直接与您的后端 API 对话。通常通过 API 管理公开 API 的开发人员使用 API 密钥来控制对 API 的访问。使用此方法可以根据不同的配置 "products".
应用策略如果您拥有管理证书创建和吊销的基础架构,那么这可能是正确的选择,这只是一种不常见的方法。话虽如此,我将调查 API 管理中可用的选项,以便能够在 APIM 网关上提取证书指纹。
您还需要为托管的 Azure API 启用客户端证书身份验证 - 此步骤将确保 Azure 携带传入请求中的任何 X-ARR-ClientCert header。
否则,Azure 会在 Request.Headers 到达您的 API.
之前将其从 Request.Headers 中移除注意:此设置仅适用于付费订阅
- 转到 https://resources.azure.com/ 和 select 您想要的 Azure 帐户
- Select 订阅 -> 资源组 -> your_resource_group -> 提供商 -> microsoft.web -> 站点 -> your_website
- 从顶部按钮进入 Read/Write 模式,进入编辑模式,然后在属性下设置 属性 "clientCertEnabled": true。
"properties": { "name": "my-site", "state": "Running", "hostNames": [ "my-site.azurewebsites.net", "(string)" ], ... "clientCertEnabled": true, ... }
文档:https://docs.microsoft.com/en-us/azure/app-service-web/app-service-web-configure-tls-mutual-auth