使用客户端证书来保护对 API 的访问

已完成

证书可用于在客户端和 API 网关之间提供 TLS 相互身份验证。 可将 API 管理网关配置为仅允许使用包含特定指纹的证书进行请求。 网关级别的授权通过入站策略进行处理。

对于气象应用,你的一些客户拥有由你信任的证书颁发机构 (CA) 颁发的客户端证书。 你要允许这些客户通过传递这些证书来进行身份验证。

在此,你将了解如何配置 API 管理,使其接受客户端证书。

TLS 客户端身份验证

借助 TLS 客户端身份验证,API 管理网关可以检查客户端请求中包含的证书,并检查以下类似属性:

属性 原因
证书颁发机构 (CA) 仅允许由特定 CA 签发的证书。
指纹 允许包含指定指纹的证书。
主题 仅允许具有指定主题的证书。
到期日期 仅允许未过期的证书。

这些属性并不互斥,可结合使用以满足你自己的策略要求。 例如,可以指定请求中传递的证书不得过期,并且已由特定证书颁发机构签名。

客户端证书经过签名,才能确保证书不被篡改。 合作伙伴向你发送证书时,请确认证书来自合作伙伴而不是来自冒名顶替者。 常用的证书验证方法有两种:

  • 检查证书颁发者。 如果颁发者是你信任的证书颁发机构,则可使用该证书。 可在 Azure 门户中配置受信任的证书颁发机构,从而自动执行此过程。

  • 如果证书由合作伙伴颁发,请确认证书来自合作伙伴。 例如,如果合作伙伴亲自交付证书,你可以确定其真实性。 这些证书称为自签名证书。

接受消耗层中的客户端证书

API 管理中的消耗层旨在符合无服务器设计原则。 如果使用 Azure Functions 等无服务器技术生成 API,则此层非常适合。 在消耗层中,必须显式启用客户端证书的使用,可在“自定义域”窗格执行此操作。 其他层级不需要此步骤。

配置网关以请求证书。

创建证书授权策略

在 API 管理网关内的入站处理策略文件中创建这些策略。

“入站处理”策略按钮。

检查客户端证书的指纹

每个客户端证书都包含一个指纹,该指纹为根据其他证书属性计算得出的哈希值。 指纹确保,自证书颁发机构颁发证书以来,证书中的值未更改。 可在策略中查看指纹。 以下示例检查请求中传递的证书的指纹。

<choose>
    <when condition="@(context.Request.Certificate == null || context.Request.Certificate.Thumbprint != "desired-thumbprint")" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>

针对已上传到 API 管理的证书检查指纹

在前面的示例中,只有一个指纹有效,因此只验证一个证书。 通常,每个客户或合作伙伴公司都会传递具有不同指纹的不同证书。 要支持此方案,请从合作伙伴处获取证书,并使用 Azure 门户中的“客户端证书”窗格将其上传到 API 管理资源。 然后将此代码添加到策略中。

<choose>
    <when condition="@(context.Request.Certificate == null || !context.Request.Certificate.Verify()  || !context.Deployment.Certificates.Any(c => c.Value.Thumbprint == context.Request.Certificate.Thumbprint))" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>

检查客户证书的证书颁发者和主题

以下示例检查请求中传递的证书的证书颁发者和主题。

<choose>
    <when condition="@(context.Request.Certificate == null || context.Request.Certificate.Issuer != "trusted-issuer" || context.Request.Certificate.SubjectName.Name != "expected-subject-name")" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>