在Azure API管理中解密承载令牌以获取acr_values

时间:2019-05-20 14:15:54

标签: azure https azure-api-management bearer-token

有什么方法可以在API管理策略中解密承载令牌,以创建条件acr_values,例如租户。

看看MS文档似乎不太可能,我希望实现以下目标:

        <when condition="@(context.Request.Headers["Authorization"] --DO MAGIC HERE-- .acr_values["tenant"] == "contoso" ">
            <set-backend-service base-url="http://contoso.com/api/8.2/" />
        </when>

或者类似此处的示例,但用于设置支持的服务:

http://devjourney.com/blog/2017/03/23/extract-jwt-claims-in-azure-api-management-policy/

我阅读过的文档: https://docs.microsoft.com/en-us/azure/api-management/api-management-transformation-policies#example-4

https://docs.microsoft.com/en-us/azure/api-management/policies/authorize-request-based-on-jwt-claims?toc=api-management/toc.json#policy

3 个答案:

答案 0 :(得分:1)

好的,所以我以一种非常怪异的方式使它工作,您可以在标头中设置解密令牌的值,然后在该标头上设置条件。

<policies>
<inbound>
    <base />
    <set-header name="tenant" exists-action="append">
        <value>@{
            string tenant = "unknown";
            string authHeader = context.Request.Headers.GetValueOrDefault("Authorization", "");
            if (authHeader?.Length > 0)
            {
                string[] authHeaderParts = authHeader.Split(' ');
                if (authHeaderParts?.Length == 2 && authHeaderParts[0].Equals("Bearer", StringComparison.InvariantCultureIgnoreCase))
                {
                    Jwt jwt;
                    if (authHeaderParts[1].TryParseJwt(out jwt))
                    {
                        tenant = (jwt.Claims.GetValueOrDefault("tenant", "unknown"));
                    }
                }
            }
            return tenant;
            }</value>
    </set-header>
    <choose>
        <when condition="@(context.Request.Headers.GetValueOrDefault("tenant", "unknown") == "some-tenant" )">
            <set-backend-service base-url="http://contoso.com/api/8.2/" />
        </when>
    </choose>
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
</outbound>
<on-error>
    <base />
</on-error>

答案 1 :(得分:1)

您尝试了.AsJwt()方法(https://docs.microsoft.com/en-us/azure/api-management/api-management-policy-expressions#ContextVariables):

<policies>
<inbound>
    <base />
    <set-header name="tenant" exists-action="append">
        <value>@{
            var jwt = context.Request.Headers.GetValueOrDefault("Authorization").AsJwt();
            return jwt?.Claims.GetValueOrDefault("tenant") ?? "unknown";
        }</value>
    </set-header>
    <choose>
        <when condition="@(context.Request.Headers.GetValueOrDefault("tenant", "unknown") == "some-tenant" )">
            <set-backend-service base-url="http://contoso.com/api/8.2/" />
        </when>
    </choose>
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
</outbound>
<on-error>
    <base />
</on-error>

如果不确定是否使用set-variable策略,我不确定是否需要它作为后端请求的标头。

答案 2 :(得分:0)

自从这个问题得到解答以来已经过去了几年,但是当我找到了一个不那么冗长的解决方案时,没有实际修改请求标头,我认为分享给其他人会很好:

<set-variable name="tenant" value="@{
        var authHeader = context.Request.Headers.GetValueOrDefault("Authorization", "");
        return authHeader.AsJwt()?.Claims.GetValueOrDefault("tenant", "");
}" />
...
<choose>
    <when condition="@(context.Variables.GetValueOrDefault("tenant", "") == "your-tenant-id")">