【Azure APIM】APIM 策略语句如何读取请求头中所携带的Cookie信息并保存为变量

发布时间 2024-01-03 22:31:22作者: 路边两盏灯

问题描述

需要在APIM策略中对请求所携带的Cookie中的token值进行JWT验证,如果获取Cookie中的值并且作为变量保存,然后在JWT 验证中使用呢?

 

问题解答

第一步:获取Cookie中的Token值

使用C#语句 @(context.Request.Headers.GetValueOrDefault("cookie", "").Split(';').Select(x => x.Trim()).Select(cookie => cookie.Split('=')).SingleOrDefault(cookie => cookie[0] == "Token")?[1]) 获取到Token信息, 需要注意:Select中的lambda表达式需要根据实际情况进行修改。

示例Cookie信息如:

Cookie:    test=123; "test222=222222222222"; test222=222222222222; token=eyJ0**LCJhbGci**************************7Yat3****H5A; test111=ey***vDH5A

请求中所携带的Cookie截图:

第二步:把值保存为变量

使用set-variable 设置token变量,存储第一步中获取的值。

示例Policy为:

<set-variable name="token" 
value
="@(context.Request.Headers.GetValueOrDefault("cookie", "").Split(';')
  .Select(x
=> x.Trim())
  .Select(cookie
=> cookie.Split('=')).SingleOrDefault(cookie => cookie[0] == "stored-token")?[1])"
/>

 

第三步:在JWT验证中获取变量值

使用 validate JWT 策略,使用 token-value="@(context.Variables.GetValueOrDefault<string>("token", "no value"))"  来代替 header-name="Authorization"

示例Policy为:

<validate-jwt 
  token-value="@(context.Variables.GetValueOrDefault<string>("token", "no value"))"
  failed-validation-httpcode
="401"
  require-expiration-time
="false"
  require-scheme
="Bearer"
  require-signed-tokens
="true"> <openid-config url=https://login.partner.microsoftonline.cn/<your azure tenant id>/v2.0/.well-known/openid-configuration />   <audiences>     <audience><your audience, GUID ></audience>   </audiences> </validate-jwt>

 

完整的Policy示例为:

<policies>
    <inbound>
        <base />
        <set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("cookie", "").Split(';').Select(x => x.Trim()).Select(cookie => cookie.Split('=')).SingleOrDefault(cookie => cookie[0] == "token")?[1])" />
        <validate-jwt token-value="@(context.Variables.GetValueOrDefault<string>("token", "no value"))" failed-validation-httpcode="401" require-expiration-time="false" require-scheme="Bearer" require-signed-tokens="true">
            <openid-config url=https://login.partner.microsoftonline.cn/xxxx-xxxx-xxxx-xxxx-xxxx/v2.0/.well-known/openid-configuration />
            <audiences>
                <audience>xxxx-xxxx-xxxx-xxxx-xxxx</audience>
            </audiences>
        </validate-jwt>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
        <choose>
            <when condition="@(context.LastError.Source == "validate-jwt")">
                <return-response>
                    <set-status code="302" reason="Unauthorized" />
                    <set-header name="Location" exists-action="override">
                        <value>https://login.partner.microsoftonline.cn/xxxx-xxxx-xxxx-xxxx-xxxx/oauth2/v2.0/authorize?response_type=code+id_token&amp;redirect_uri=<redirect_uri>&amp;client_id=%20xxxx-xxxx-xxxx-xxxx-xxxx&amp;scope=openid+profile+email&amp;response_mode=form_post&amp;nonce=eef3d47c873242ddb09b28ed1f997f1b_20230926163347&amp;state=redir%3D%252F</value>
                    </set-header>
                </return-response>
            </when>
        </choose>
    </on-error>
</policies>

 

 

 

参考资料

validate-jwt :https://learn.microsoft.com/en-us/azure/api-management/validate-jwt-policy

Set variable : https://learn.microsoft.com/en-us/azure/api-management/set-variable-policy#example