Azure APIM 基于两个不同的声明验证 JWT
Azure APIM Validate JWT based on two different claims
我正在尝试在 Azure APIM 中创建一个策略,以根据两个不同的声明验证 JWT 令牌(Azure AD 令牌)。
我的 API 可能会被其他应用程序或用户使用 - 它可能会从用户上下文或应用程序上下文中调用。因此,令牌可能包含“scp”声明,例如user_impersonation
或“角色”声明,如 [ "CallApiAsAnApp" ]
。
From the documentation,我还没有找到任何方法来做到这一点。这是可能的还是我必须实现自定义代码才能在 API 级别执行此操作?添加到保单中“必需索赔”的任何索赔都将成为强制性的。在声明级别似乎没有任何“匹配任何”选项,只有值级别。
正如您提到的,令牌可能包含 scp
声明或 roles
声明,看来您的令牌有时以“委托”类型生成,有时以“应用程序”类型生成。您只需像下面的屏幕截图那样配置 <validate-jwt>
策略,在其中添加两个声明并选择“任何声明”。
之后,如果令牌只包含一个声明,则可以验证。
对了,请检查你的两种情况下的token是否有相同的“Audiences”,否则你的需求可能无法通过上面的配置实现。
最后,我能找到解决问题的唯一方法是使用带有自定义代码的 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>
我正在尝试在 Azure APIM 中创建一个策略,以根据两个不同的声明验证 JWT 令牌(Azure AD 令牌)。
我的 API 可能会被其他应用程序或用户使用 - 它可能会从用户上下文或应用程序上下文中调用。因此,令牌可能包含“scp”声明,例如user_impersonation
或“角色”声明,如 [ "CallApiAsAnApp" ]
。
From the documentation,我还没有找到任何方法来做到这一点。这是可能的还是我必须实现自定义代码才能在 API 级别执行此操作?添加到保单中“必需索赔”的任何索赔都将成为强制性的。在声明级别似乎没有任何“匹配任何”选项,只有值级别。
正如您提到的,令牌可能包含 scp
声明或 roles
声明,看来您的令牌有时以“委托”类型生成,有时以“应用程序”类型生成。您只需像下面的屏幕截图那样配置 <validate-jwt>
策略,在其中添加两个声明并选择“任何声明”。
之后,如果令牌只包含一个声明,则可以验证。
对了,请检查你的两种情况下的token是否有相同的“Audiences”,否则你的需求可能无法通过上面的配置实现。
最后,我能找到解决问题的唯一方法是使用带有自定义代码的 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>