Azure编程笔记(4):配置Cloud Service的证书



我们在Microsoft Azure中部署CloudService的时候,可能会用到证书。通常在两种情况下需要用到证书。一是把证书安装在服务器端。此时证书用来建立HTTPS/SSL连接,以便保护传输中的数据。二是把证书部署在客户端。此时客户端发起连接请求时,它会把证书信息添加到请求中。服务器端收到请求之后,会验证其中的证书是不是合法的证书。这种情况下证书是用来验证用户的。接下来我们分两种情况来讨论如何管理证书。

把证书安装在服务器端

假设我们用ASP .NETWeb API开发一个WebRoleCloudService。如果我们希望用户连接这个由WebAPI开发的服务器端时需要建立HTTPS连接,那么我们就得在服务器端安装证书。CloudService是部署在Azure的虚拟机上,我们自然不喜欢每次部署CloudService的时候都远程登陆到虚拟机上手动安装证书。

为了能够在部署Cloud Service的时候自动安装证书,我们首先需要把证书上传到CloudService上。在Azure的管理网站(https://manage.windowsazure.cn)的CloudService相应的网页上,我们可以找到管理证书的页面,如下图所示:

 

接着我们在Cloud ServiceServiceDefinition.csdef文件中添加如下内容:

   

<Certificates>
  <Certificate name="xxxxyyyy" storeLocation="LocalMachine" storeName="My" />
</Certificates>

这里我们指定了Cloud Service需要用到一个证书。该证书正是我们刚刚上传的证书。在部署CloudService时,Azure会自动把该证书安装到虚拟机上去。

接下来我们打开一个HTTPS的端口。这需要在CloudServiceServiceDefinition.csdef文件中再添加如下内容:

<Sites>
    <Site name="Web">
    <Bindings>
        <Binding name="Endpoint1" endpointName="Endpoint1" />
    </Bindings>
    </Site>
</Sites>
<Endpoints>
    <InputEndpoint name="Endpoint1" protocol="https" port="443" certificate="xxxxyyyy"/>
</Endpoints>

在上述内容中我们定义了一个端口是 443 EndPoint ,与这个 EndPoint 连接的协议是 HTTPS 。我们还设置了建立 HTTPS 需要的证书。当客户端试图连接该服务器端时,部署着 CloudService 的虚拟机上的 IIS 就会自动找到该证书,并用该证书建立 HTTPS 连接。

把证书安装在客户端

我们在开发一个服务器端程序时,经常会限制只有特定的用户才能连接该服务器。通常有两种办法实现限制。一种办法是给合法的用户建立账号和密码,让合法的用户在使用服务之前先输入用户名和密码进行验证。另一种办法是给合法用户一张证书。这些用户来建立连接使用服务的时候都要附上证书。服务器端会根据请求中的证书来验证请求是否合法。

如果是用证书来验证用户,那么需要在客户端安装证书。假设客户端用HttpClient和服务器端建立连接,那么客户端可以通过如下代码在请求中附上证书信息:

X509Certificate2 certificate = GetCertificateByThumprint(thumprint);
var webRequestHandler = new WebRequestHandler();
webRequestHandler.ClientCertificateOptions= ClientCertificateOption.Manual;
webRequestHandler.UseDefaultCredentials= false;
webRequestHandler.ClientCertificates.Add(certificate);

httpClient= new HttpClient(webRequestHandler);

为了让服务器端在接收到请求时验证证书信息,我们首先要在服务器端的配置中添加一个 MessageHandler 。如果是用 ASP.NET WEBAPI 实现服务器端,可以在 WebApiApplication . Application_Start 添加如下代码:

GlobalConfiguration.Configuration.MessageHandlers.Add(new CertificateAuthenticationHandler());

Handler 可以用如下代码实现:

public class CertificateAuthenticationHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        X509Certificate2 certificate = request.GetClientCertificate();
        if(!CertificateValidator.IsValid(certificate))
        {
            return Task<HttpResponseMessage>.Factory.StartNew(() =>
                request.CreateResponse(HttpStatusCode.Unauthorized));
        }

        return base.SendAsync(request, cancellationToken);
    }
}

在上述代码中,我们每收到一个请求,都会从请求中得到附带的证书信息,然后再验证证书是否合法。如果证书无效,则返回代码为401HTTP错误代码。

上述代码并没有问题,可是当我们运行服务器端代码是,就会发现并没有从请求中读出的证书信息总是null

不能从请求中读出证书信息的原因是服务器端的IIS没有接收证书。在IIS里有一个SSL选项是用来决定是否接收证书。它的默认设置如下:

 

IIS的默认设置里,来自客户端的证书被忽视了,那么自然前面的代码不能得到证书信息。因此我们不得不让服务器端的IIS接受来自客户端的证书。为了实现这一目的,我们首先需要在服务器端代码的web.config文件里添加如下内容:

<system.webServer>
  <security xdt:Transform="Insert">
    <access sslFlags="Ssl, SslNegotiateCert" />
  </security>
</system.webServer>

上述配置文件定了IIS的配置参数。接下来我们需要写一个脚本来修改IIS的配置参数:

%windir%\system32\inetsrv\appcmd unlock config/section:system.webServer/security/access

为了让服务器端程序对应的Web Role在启动的时候自动调用上述脚本(假设命名为UnlockConfig.cmd),我们在CloudServiceServiceDefinition.csdef中添加如下内容:

<Startup>
    <Task commandLine="StartupTasks\UnlockConfig.cmd" executionContext="elevated" taskType="background" />
</Startup>

上述内容定义了在Web Role启动的时候需要执行一个任务,即在Web Role启动的时候自动执行前面的脚本文件修改IIS的配置,接收来自客户端的证书。在修改IIS的配置参数之后,IIS的界面显示如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值