访问 Azure Worker Role 中托管的 ApiController 中的客户端证书
Posted
技术标签:
【中文标题】访问 Azure Worker Role 中托管的 ApiController 中的客户端证书【英文标题】:Access Client certificate in ApiController hosted in Azure Worker Role 【发布时间】:2018-02-05 08:41:21 【问题描述】:这可能是一个重复的问题,但我仍然找不到任何可以解决我的问题的答案,所以再次发布。
我有一个 azure worker 角色,并且我使用 Owin selfhost 向它添加了一个 ApiController(请参阅 this 以供参考)。
在我的自定义控制器中,我有一个 POST api,它尝试通过从 Request 对象中提取证书来进行客户端证书身份验证,但是在部署到 azure cemulator 时,证书始终为 null。
这是我的示例客户端代码:
enter code here
公共静态异步任务 GetResponseAsync(WebApiRequestInfo webApiRequestInfo)
if (webApiRequestInfo == null)
throw new ArgumentNullException("webApiRequestInfo");
WebRequestHandler requestHandler = null;
if (webApiRequestInfo.Certificate != null)
requestHandler = new WebRequestHandler ClientCertificateOptions = ClientCertificateOption.Manual ;
requestHandler.ClientCertificates.Add(webApiRequestInfo.Certificate);
using (var client = requestHandler != null
? new HttpClient(requestHandler) BaseAddress = webApiRequestInfo.BaseUrl
: new HttpClient BaseAddress = webApiRequestInfo.BaseUrl)
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue(webApiRequestInfo.MediaType));
var method = new HttpMethod(webApiRequestInfo.HttpMethod);
var request = new HttpRequestMessage(method, webApiRequestInfo.RelativeUrl)
Content =
webApiRequestInfo.Content != null
? new StringContent(JsonConvert.SerializeObject(webApiRequestInfo.Content), Encoding.UTF8,
"application/json")
: null
;
var response = await client.SendAsync(request);
return response;
控制器代码如下所示:
[HttpPost]
public async Task<HttpResponseMessage> GetPackage([FromBody]PackageInfo packageInfo)
string correlationId = null;
var logger = TraceLogger<LogData>.Logger;
try
if (string.IsNullOrEmpty(packageInfo.Partner))
throw new ArgumentException("Partner undefined");
if (string.IsNullOrEmpty(packageInfo.ServiceEnvironment))
throw new ArgumentException("ServiceEnvironment undefined");
if (string.IsNullOrEmpty(packageInfo.StorageEnvironment))
throw new ArgumentException("StorageEnvironment undefined");
var cert1 = Request.GetClientCertificate();// this is always null
我是否缺少某些东西,或者这是为 azure 模拟器设计的东西。我想在部署到云服务之前澄清这一点,以确保这里没有遗漏任何东西。任何解决此问题的建议都会非常有帮助。
【问题讨论】:
请查看webApiRequestInfo.BaseUrl
,是http还是https?
【参考方案1】:
问题在于证书颁发机构,因此 IIS 从请求中过滤掉了证书。在 CA 白名单中使用正确的证书开始一切正常。
【讨论】:
【参考方案2】:根据我的测试,我可以在 ASP.NET Web API(托管在 Azure 工作者角色中)控制器操作中访问客户端证书。以下示例代码供您参考。
TestController.cs
public class TestController : ApiController
public HttpResponseMessage Get()
return new HttpResponseMessage()
Content = new StringContent("Hello from OWIN!")
;
public HttpResponseMessage Get(int id)
var Thumbprint = Request.GetClientCertificate().Thumbprint.ToString();
string msg = String.Format("Hello from OWIN (id = 0)", id);
return new HttpResponseMessage()
Content = new StringContent(msg)
;
在控制台应用中发送请求
X509Certificate2 certificate = new X509Certificate2(certName, password);
var Thumbprint = certificate.Thumbprint.ToString();
Console.WriteLine($"client certificate Thumbprint: Thumbprint");
WebRequestHandler requestHandler = new WebRequestHandler();
requestHandler = new WebRequestHandler ClientCertificateOptions = ClientCertificateOption.Manual ;
requestHandler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
requestHandler.ClientCertificates.Add(certificate);
using (var client = new HttpClient(requestHandler))
HttpResponseMessage response = await client.GetAsync("https://127.0.0.1:9527/test/5");
if (response.IsSuccessStatusCode)
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Received response: content");
else
Console.WriteLine($"Error, received status code response.StatusCode: response.ReasonPhrase");
可以在 Web API 控制器操作中访问客户端证书
控制台应用输出
【讨论】:
您的证书是自签名证书还是由作为服务器受信任列表的受信任 CA 签名的? 在我的测试中,我使用的是自签名证书。以上是关于访问 Azure Worker Role 中托管的 ApiController 中的客户端证书的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法使用 Slow Cheetah 来转换 Azure Worker Role 中的 app.config?
Azure ARM (17) 基于角色的访问控制 (Role Based Access Control, RBAC) - 自定义Role