我正在尝试在 Azure APIM 中创建一个策略,以根据两个不同的声明验证 JWT 令牌(Azure AD 令牌)。
我的 API 可以由其他应用程序或用户使用 - 它可以从用户上下文或应用程序上下文中调用。因此,令牌可能包含“scp”声明,例如
user_impersonation
或“角色”声明,例如 [ "CallApiAsAnApp" ]
。
从文档中,我还没有找到任何方法来做到这一点。这是可能的还是我必须实现自定义代码才能在 API 级别执行此操作?保单中添加到“必需索赔”中的任何索赔都将成为强制性索赔。在声明级别似乎没有任何“匹配任何”选项,只有值级别。
最后,我能找到解决问题的唯一方法是使用 Choose 元素而不是 validate-jwt 以及自定义代码(这是我希望避免的方式)。基本上,我将经过验证的 JWT 令牌保存到变量中,然后使用 if / elseif 来确定令牌是否可接受。工作相关配置如下
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" require-scheme="Bearer" output-token-variable-name="valid-jwt">
<openid-config url="https://login.microsoftonline.com/tenantid/v2.0/.well-known/openid-configuration" />
<issuers>
<issuer>https://sts.windows.net/tenantid/</issuer>
</issuers>
</validate-jwt>
<choose>
<when condition="@{
var jwt = (Jwt)context.Variables["valid-jwt"];
if(jwt.Claims.ContainsKey("roles")){
var roles = jwt.Claims["roles"];
return !Array.Exists(roles, element => element == "MyRoleName");
} else if (jwt.Claims.ContainsKey("scp")){
var scp = jwt.Claims["scp"];
return !Array.Exists(scp, element => element == "user_impersonation");
} else { return true; }
}">
<return-response>
<set-status code="401" reason="Unauthorized" />
</return-response>
</when>
<otherwise />
</choose>
对于可能偶然发现此页面的人,运算符(任何/全部)用于声明中的值 所有必需的声明都需要包含在使用 OOB 策略的令牌中,操作员仅帮助验证值
举个例子
<inbound>
<required-claims>
<claim name="foo" match="any">
<value>bar</value>
<value>baar</value>
<value>baar</value>
<value>baaar</value>
</claim>
</required-claims>
</validate-jwt>
</inbound>
将验证声明“foo”中的任何值,如果您使用运算符“all”而不是any,则声明必须包含所有值
此处的文档中指定了:https://learn.microsoft.com/en-us/azure/api-management/validate-jwt-policy#claim-attributes