创建 Azure API 管理策略时的 XML 语法帮助

Posted

技术标签:

【中文标题】创建 Azure API 管理策略时的 XML 语法帮助【英文标题】:XML syntax help while creating Azure API Management policy 【发布时间】:2020-08-20 12:52:13 【问题描述】:

我有以下策略语法,当与 GET 请求一起传递时,它仅适用于一个证书。

<choose>
    <when condition="@(context.Request.Certificate != null && !context.Request.Certificate.Issuer.Contains("CN=itv.mit-xperts.com"))">
        <return-response>
            <set-status code="403" reason="Invalid client certificate Issuer" />
        </return-response>
    </when>
</choose>

如果我使用策略在两个证书之间进行验证,那么它总是会转到 403,因为 OR 语句总是返回 true:

<choose>
    <when condition="@((context.Request.Certificate != null) && (!context.Request.Certificate.Issuer.Contains("CN=itv.mit-xperts.com") || !context.Request.Certificate.Issuer.Contains("CN=DigiCert Test SHA2 Intermediate CA-1")))">
        <return-response>
            <set-status code="403" reason="Invalid client certificate Issuer" />
        </return-response>
    </when>
</choose>

API 无需证书即可工作,但如果通过了证书,则“何时”标签可能会或可能不会采取行动。我希望仅在使用具有任何其他颁发者的证书时才使条件变为 403。 发行者信息根据证书包含许多不同的属性,但 CN=some-text 仍然很常见。

我对 XML 及其语法或功能一无所知。

以下 Microsoft Docs 可能有帮助,但我没有找到任何可能有帮助的语法:

https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-mutual-certificates-for-clients#checking-the-issuer-and-subject

https://docs.microsoft.com/en-us/azure/api-management/api-management-policy-expressions

https://docs.microsoft.com/en-us/azure/api-management/api-management-transformation-policies

【问题讨论】:

【参考方案1】:

看来您的问题不在于语法,而在于布尔逻辑:

(context.Request.Certificate != null) && 
(
 !context.Request.Certificate.Issuer.Contains("CN=itv.mit-xperts.com") ||
 !context.Request.Certificate.Issuer.Contains("CN=DigiCert Test SHA2 Intermediate CA-1")
)

只要 issuer 不包含 CN=itv.mit-xperts.com 和不包含 CN=itv.mit-xperts.com,这将评估为 true

看来您在这里真正想要的是一个 AND 条件:

(context.Request.Certificate != null) && 
(
 !context.Request.Certificate.Issuer.Contains("CN=itv.mit-xperts.com") &&
 !context.Request.Certificate.Issuer.Contains("CN=DigiCert Test SHA2 Intermediate CA-1")
)

仅当颁发者不包含 CN=itv.mit-xperts.com 并且它也不包含 CN=DigiCert Test SHA2 Intermediate CA-1 时才会如此

另外,您似乎可以将 NOT 移到括号外并将 AND 更改为 OR,这可能更容易理解:

(context.Request.Certificate != null) && 
!(
 context.Request.Certificate.Issuer.Contains("CN=itv.mit-xperts.com") ||
 context.Request.Certificate.Issuer.Contains("CN=DigiCert Test SHA2 Intermediate CA-1")
)

当颁发者不包含CN=itv.mit-xperts.comCN=DigiCert Test SHA2 Intermediate CA-1 时,这是正确的

看起来您也可以为此使用 LINQ:

var validIssuers = new [] 

    "CN=itv.mit-xperts.com",
    "CN=DigiCert Test SHA2 Intermediate CA-1",
;
var issuer = context.Request?.Certificate.Issuer;

return issuer != null && !validIssuers.Any(i => issuer.Contains(i));

【讨论】:

以上是关于创建 Azure API 管理策略时的 XML 语法帮助的主要内容,如果未能解决你的问题,请参考以下文章

Azure API 管理 - 仅在设置标记时应用策略

Azure API 管理策略 302

使用查询参数获取令牌的 Azure API 管理策略

在 Azure API 管理中,当不需要订阅时,如何为 API 解决产品级策略?

如何在 Azure API 管理策略中重用响应上下文变量?

如何使用 Terraform 将 log-to-eventhub 策略添加到 Azure API 管理策略