Azure APIM 根据两种不同的声明验证 JWT

问题描述 投票:0回答:3

我正在尝试在 Azure APIM 中创建一个策略,以根据两个不同的声明验证 JWT 令牌(Azure AD 令牌)。

我的 API 可以由其他应用程序或用户使用 - 它可以从用户上下文或应用程序上下文中调用。因此,令牌可能包含“scp”声明,例如

user_impersonation
或“角色”声明,例如
[ "CallApiAsAnApp" ]

从文档中,我还没有找到任何方法来做到这一点。这是可能的还是我必须实现自定义代码才能在 API 级别执行此操作?保单中添加到“必需索赔”中的任何索赔都将成为强制性索赔。在声明级别似乎没有任何“匹配任何”选项,只有值级别。

azure oauth-2.0 azure-api-management
3个回答
3
投票

最后,我能找到解决问题的唯一方法是使用 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>

0
投票

正如您提到的,令牌可能包含

scp
声明或
roles
声明,似乎您的令牌有时以“委托”类型生成,有时以“应用程序”类型生成。您只需像下面的屏幕截图一样配置
<validate-jwt>
策略,在其中添加两个声明并选择“任何声明”。

此后,如果令牌仅包含一项声明,则可以验证该令牌。

顺便请检查一下,两种情况下你的token是否有相同的“Audiences”,否则上面的配置可能无法实现你的需求。


0
投票

对于可能偶然发现此页面的人,运算符(任何/全部)用于声明中的值 所有必需的声明都需要包含在使用 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

© www.soinside.com 2019 - 2024. All rights reserved.