Azure API管理:验证jwt令牌范围

时间:2017-06-14 08:52:09

标签: api oauth-2.0 jwt azure-api-management

我们希望使用validate-jwt策略保护API操作调用,但是当我使用required-claims检查范围时,我遇到了问题。 示例:我有一个带有范围的令牌,其中包含几个值,如" xxx.READ xxx.WRITE yyy.READ yyy.WRITE ..." 对于特定操作,我想使用validate-jwt策略来检查令牌是否包含链接的范围,如:

    <required-claims>
            <claim name="scp" match="any">
                <value>xxx.READ</value>
            </claim>
    </required-claims>

但是由于scp中的多个值,验证总是失败...如何检查此声明?我之前是否必须提取scp值?如果是,我该怎么做?

提前致谢

3 个答案:

答案 0 :(得分:2)

多值声明应在JWT标记内表示为数组:

"scp": ["xxx.READ", "xxx.WRITE", "yyy.READ", "yyy.WRITE"]

您发布的策略配置完全支持此方案。

但是如果你把它们表示为一个单独的字符串(“xxx.READ xxx.WRITE yyy.READ yyy.WRITE”)那么你必须使用手动表达式来验证这样的标记,这些都是这样的:

<choose>
    <when condition="@(context.Request.Headers.ContainsKey("Authorization"))">
        <set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization", string.Empty).AsJwt())" />
        <choose>
            <when condition="@{
if (context.Variables["token"] == null) {
    return false;
}

var scp = ((Jwt)context.Variables["token"]).Claims.GetValueOrDefault("scp", (string[])null);
if (scp == null || scp.Length == 0) {
    return false;
}

return scp.Any(c => c.Contains("xxx.READ"));
            }">
                <return-response response-variable-name="existing response variable">
                    <set-status code="401" reason="Unauthorized" />
                </return-response>
            </when>
        </choose>
    </when>
    <otherwise>
        <return-response response-variable-name="existing response variable">
            <set-status code="401" reason="Unauthorized" />
        </return-response>
    </otherwise>
</choose>

答案 1 :(得分:1)

要验证 JWT 中是否存在范围,请使用设置为“,”的 separator 属性,因为这是一个多值声明,如下所示:"scope": ["api1.write ","roles","profile"] .

例如:

<required-claims>
   <claim name="scope" match="all" separator=",">
        <value>api1.write</value>
   </claim>
</required-claims>

答案 2 :(得分:0)

我也在使用B2C设置API管理,但我遇到了完全相同的问题。 我正在使用的解决方案更容易。

<policies>
    <inbound>
        <base />
        <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="The Scope claim does not contain the read permission." require-expiration-time="true" require-scheme="Bearer" require-signed-tokens="true" clock-skew="0">
            <openid-config url="{{your-openid-config-url}}" />
            <required-claims>
                <claim name="scp" match="any" separator=" ">
                    <value>read</value>
                </claim>
            </required-claims>
        </validate-jwt>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>