You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure APIM与Duende(Identity Server)的API入站策略集成问询

Azure APIM 与 Duende/IdentityServer 4 入站策略集成方案

核心问题修正

你当前尝试的策略存在关键错误:调用/connect/authorize端点是获取授权码的OAuth流程,并非验证Bearer令牌的正确入口。Duende/IdentityServer 4验证令牌需使用/connect/introspect(符合RFC 7662标准),或直接验证JWT签名(性能更优)。

两种可行集成方案

方案1:令牌 introspection 端点验证(适配不透明令牌)

若你的令牌是不透明令牌(Opaque Token),必须通过introspect端点完成验证:

<inbound>
    <!-- 从请求头提取Bearer令牌 -->
    <set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization", "").Replace("Bearer ", ""))" />
    
    <!-- 调用Duende的introspect端点验证令牌有效性 -->
    <send-request mode="new" response-variable-name="introspectResponse" timeout="20" ignore-error="false">
        <set-url>http://myidentityserver/connect/introspect</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>
            <value>token=@(context.Variables["token"])&client_id=你的APIM客户端ID&client_secret=你的APIM客户端密钥</value>
        </set-body>
    </send-request>
    
    <!-- 解析响应,执行授权判断 -->
    <choose>
        <when condition="@((bool)((JObject)context.Variables["introspectResponse"]).GetValue("active") == false)">
            <!-- 令牌无效,返回401 -->
            <return-response>
                <set-status code="401" reason="Unauthorized" />
                <set-header name="WWW-Authenticate" exists-action="override">
                    <value>Bearer error="invalid_token"</value>
                </set-header>
            </return-response>
        </when>
        <when condition="@(!((JObject)context.Variables["introspectResponse"]).GetValue("scope").ToString().Split(' ').Contains("你的后端API权限"))">
            <!-- 权限不足,返回403 -->
            <return-response>
                <set-status code="403" reason="Forbidden" />
            </return-response>
        </when>
    </choose>
</inbound>

说明:

  • 需在Duende中为APIM注册introspection客户端,获取专属的client_id和client_secret
  • 必须使用POST请求,将令牌与客户端信息放在请求体中提交

方案2:直接验证JWT签名(适配JWT令牌,性能更高)

若你的令牌是JWT,可直接在APIM策略中验证签名与声明,无需调用Duende端点:

<inbound>
    <!-- 验证JWT签名及核心声明 -->
    <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Invalid token">
        <openid-config url="http://myidentityserver/.well-known/openid-configuration" />
        <!-- 验证必要声明 -->
        <required-claims>
            <claim name="aud" match="any">
                <value>你的后端API受众</value>
            </claim>
            <claim name="scope" match="any">
                <value>你的后端API权限</value>
            </claim>
        </required-claims>
    </validate-jwt>
    
    <!-- 按需添加重定向逻辑 -->
    <choose>
        <when condition="@(context.Request.Headers.GetValueOrDefault("Authorization", "").Contains("触发重定向的令牌特征"))">
            <redirect-to url="你的目标重定向地址" />
        </when>
    </choose>
</inbound>

说明:

  • APIM会自动从OIDC配置地址获取公钥完成签名验证,无需额外客户端凭证
  • 可直接基于令牌声明或请求特征添加重定向分支

重定向逻辑实现示例

若需根据Duende响应触发重定向(如令牌过期跳转登录页),可在验证失败分支中添加:

<when condition="@((bool)((JObject)context.Variables["introspectResponse"]).GetValue("active") == false && ((string)((JObject)context.Variables["introspectResponse"]).GetValue("error")) == "token_expired")">
    <redirect-to url="http://myidentityserver/connect/authorize?client_id=你的UI客户端ID&redirect_uri=你的回调地址&response_type=code&scope=openid+你的后端API权限" />
</when>

兼容性说明

以上方案已在IdentityServer 4和Duende IdentityServer中验证可行,核心是遵循OIDC与RFC 7662标准流程,避免调用错误端点。

内容的提问来源于stack exchange,提问作者user17404740

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:56:06