问题描述
需要在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&redirect_uri=<redirect_uri>&client_id=%20xxxx-xxxx-xxxx-xxxx-xxxx&scope=openid+profile+email&response_mode=form_post&nonce=eef3d47c873242ddb09b28ed1f997f1b_20230926163347&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