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

XML syntax help while creating Azure API Management policy

我有以下策略语法,当与 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 语句始终 returns 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 无需证书即可工作,但如果通过了证书,则 "when" 标签可能会也可能不会采取行动。我希望只有在使用任何其他颁发者的证书时,条件才会转到 403。 颁发者信息根据证书包含许多不同的属性,但 CN=some-text 仍然很常见。

我不了解 XML 及其语法或功能。

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

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

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

(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=itv.mit-xperts.com

,这将评估为真

看来您真正想要的是一个 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));