Azure API 网关策略
Azure API Gateway Policy
我想使用来自我的身份验证服务的响应为请求添加查询参数。这些是示例:
<policies>
<inbound>
<!-- Extract Token from Authorization header parameter -->
<set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization","JWT").Split(' ').Last())" />
<!-- Send request to Token Server to validate token (see RFC 7662) -->
<send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="false">
<set-url>AUTH Service</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-body>@($"token={(string)context.Variables["token"]}")</set-body>
</send-request>
<choose>
<when condition="@((bool)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["active"] == false)">
<return-response response-variable-name="existing response variable">
<set-status code="401" reason="Unauthorized" />
</return-response>
</when>
<otherwise>
<set-query-parameter name="domain_id" exists-action="append">
<value>
@((string)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["content"]["domain_id"])
</value>
</set-query-parameter>
</otherwise>
</choose>
<base />
</inbound>
</policies>
但是我收到这个错误:
{
"messages": [
{
"message": "Expression evaluation failed.",
"expression": "(string)((IResponse)context.Variables[\"tokenstate\"]).Body.As<JObject>()[\"content\"]",
"details": "Object reference not set to an instance of an object."
},
"Expression evaluation failed. Object reference not set to an instance of an object.",
"Object reference not set to an instance of an object."
]
}
知道我应该怎么做吗?
通过从我的 AUTH 服务获取解码的 JWT 并将其添加到后端请求
谢谢
出于性能原因,APIM 服务始终避免在内存中缓存完整的 request/response 正文,因此当您调用 ((IResponse)context.Variables["tokenstate"]).Body.As () 响应直接从 auth 服务器流式传输,同时转换为 JObject,因此在此之后使用它,第二次调用 .Body.As() 将产生空值。
要避免这种情况,您有两个选择:
- call
((IResponse)context.Variables["tokenstate"]).Body.As<JObject>(true)
- 此附加参数指示服务在内存中缓存响应,以便将其保留以供以后检查。但是稍后再次调用 .As() 将再次将原始响应解析为 JSON 再次执行相同的工作并影响性能。
- 或
<set-variable name="tokenstate" value="((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()" />
。这将用解析的 JSON 主体覆盖 tokenstate 变量的值,以后可以多次使用,因为它现在将存储在内存中。
只是为了添加一个解决方案,如果您需要验证请求中的某些字段 api 政策可能会使用:
将其放在入站标签下方:
<set-variable name="<some>" value="@(context.Request.Body.As<string>())" />
<choose>
<when condition="@(!((string) context.Variables["<some>"]).Contains("<some>"))">
<return-response>
<set-status code="400" reason="badRequest" />
<set-header name="<some>" exists-action="override">
<value><some></value>
</set-header>
<set-body />
</return-response>
</when>
<otherwise>
<return-response />
</otherwise>
</choose>
我想使用来自我的身份验证服务的响应为请求添加查询参数。这些是示例:
<policies>
<inbound>
<!-- Extract Token from Authorization header parameter -->
<set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization","JWT").Split(' ').Last())" />
<!-- Send request to Token Server to validate token (see RFC 7662) -->
<send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="false">
<set-url>AUTH Service</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-body>@($"token={(string)context.Variables["token"]}")</set-body>
</send-request>
<choose>
<when condition="@((bool)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["active"] == false)">
<return-response response-variable-name="existing response variable">
<set-status code="401" reason="Unauthorized" />
</return-response>
</when>
<otherwise>
<set-query-parameter name="domain_id" exists-action="append">
<value>
@((string)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["content"]["domain_id"])
</value>
</set-query-parameter>
</otherwise>
</choose>
<base />
</inbound>
</policies>
但是我收到这个错误:
{
"messages": [
{
"message": "Expression evaluation failed.",
"expression": "(string)((IResponse)context.Variables[\"tokenstate\"]).Body.As<JObject>()[\"content\"]",
"details": "Object reference not set to an instance of an object."
},
"Expression evaluation failed. Object reference not set to an instance of an object.",
"Object reference not set to an instance of an object."
]
}
知道我应该怎么做吗?
通过从我的 AUTH 服务获取解码的 JWT 并将其添加到后端请求
谢谢
出于性能原因,APIM 服务始终避免在内存中缓存完整的 request/response 正文,因此当您调用 ((IResponse)context.Variables["tokenstate"]).Body.As () 响应直接从 auth 服务器流式传输,同时转换为 JObject,因此在此之后使用它,第二次调用 .Body.As() 将产生空值。
要避免这种情况,您有两个选择:
- call
((IResponse)context.Variables["tokenstate"]).Body.As<JObject>(true)
- 此附加参数指示服务在内存中缓存响应,以便将其保留以供以后检查。但是稍后再次调用 .As() 将再次将原始响应解析为 JSON 再次执行相同的工作并影响性能。 - 或
<set-variable name="tokenstate" value="((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()" />
。这将用解析的 JSON 主体覆盖 tokenstate 变量的值,以后可以多次使用,因为它现在将存储在内存中。
只是为了添加一个解决方案,如果您需要验证请求中的某些字段 api 政策可能会使用: 将其放在入站标签下方:
<set-variable name="<some>" value="@(context.Request.Body.As<string>())" />
<choose>
<when condition="@(!((string) context.Variables["<some>"]).Contains("<some>"))">
<return-response>
<set-status code="400" reason="badRequest" />
<set-header name="<some>" exists-action="override">
<value><some></value>
</set-header>
<set-body />
</return-response>
</when>
<otherwise>
<return-response />
</otherwise>
</choose>