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

WSO2 APIM 4.0.0 Token API添加CORS响应头失败求助

问题描述

环境:WSO2 APIM 4.0.0,以WSO2 IS 5.11.0作为密钥管理器
前端调用APIM托管API时,浏览器控制台出现CORS错误:

Access to XMLHttpRequest at 'https://apim.mydomain/oauth2/token' from origin 'https://frontendapp.mydomain' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

通过Postman调用https://apim.mydomain/oauth2/token确认响应缺少Access-Control-Allow-Origin头。已尝试配置APIM跳过Token API同步、添加自定义Token API文件、配置IS的CORS规则,但问题未解决。


解决方案

针对WSO2 APIM 4.0.0 + IS 5.11.0的Token API CORS问题,按以下步骤修正:

1. 修正自定义Token API配置

文件名匹配同步规则

确保自定义API文件名为_TokenAPI_.xml(注意大写的API),与APIM的deployment.toml中跳过列表的_TokenAPI_.xml完全一致,避免因大小写不匹配导致系统自动覆盖自定义配置。

完善API定义(包含OPTIONS预检请求处理)

更新wso2am-4.0.0/repository/deployment/server/synapse-configs/default/api/_TokenAPI_.xml内容,添加OPTIONS方法处理逻辑,并调整Handler顺序:

<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse" name="_WSO2AMTokenAPI_" context="/oauth2/token" binds-to="default">
    <!-- 处理POST令牌请求 -->
    <resource methods="POST" binds-to="default" url-mapping="/*" faultSequence="_token_fault_">
        <inSequence>
            <property name="uri.var.portnum" expression="get-property('keyManager.port')"/>
            <property name="uri.var.hostname" expression="get-property('keyManager.hostname')"/>
            <send>
                <endpoint>
                    <http uri-template="https://{uri.var.hostname}:{uri.var.portnum}/oauth2/token">
                        <timeout>
                            <duration>60000</duration>
                            <responseAction>fault</responseAction>
                        </timeout>
                    </http>
                </endpoint>
            </send>
        </inSequence>
        <outSequence>
            <!-- 为响应添加CORS头 -->
            <property name="Access-Control-Allow-Origin" value="https://frontendapp.mydomain" scope="transport"/>
            <property name="Access-Control-Allow-Credentials" value="true" scope="transport"/>
            <send/>
        </outSequence>
    </resource>
    <!-- 处理OPTIONS预检请求 -->
    <resource methods="OPTIONS" binds-to="default" url-mapping="/*">
        <inSequence>
            <property name="Access-Control-Allow-Origin" value="https://frontendapp.mydomain" scope="transport"/>
            <property name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS" scope="transport"/>
            <property name="Access-Control-Allow-Headers" value="authorization,Content-Type" scope="transport"/>
            <property name="Access-Control-Allow-Credentials" value="true" scope="transport"/>
            <respond/>
        </inSequence>
    </resource>
    <handlers>
        <!-- CORSHandler放在最前面,优先处理预检请求 -->
        <handler class="org.wso2.carbon.apimgt.gateway.handlers.security.CORSRequestHandler">
            <property name="apiImplementationType" value="ENDPOINT"/>
            <property name="allowHeaders" value="authorization,Content-Type"/>
            <property name="allowedOrigins" value="https://frontendapp.mydomain"/>
            <property name="allowedMethods" value="GET,POST,OPTIONS"/>
            <property name="supportsCredentials" value="true"/>
        </handler>
        <handler class="org.wso2.carbon.apimgt.gateway.handlers.common.SynapsePropertiesHandler"/>
        <handler class="org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerCacheExtensionHandler"/>
    </handlers>
</api>

注意:将https://frontendapp.mydomain替换为实际前端域名,若无需带凭证请求可使用*,但生产环境建议指定具体域名。

2. 调整APIM的deployment.toml配置

确保跳过列表配置正确,同时添加网关全局CORS配置(可选但推荐):

[apim.sync_runtime_artifacts.gateway.skip_list]
apis = ["_OpenService_.xml","_RevokeAPI_.xml", "_TokenAPI_.xml"]

# 全局网关CORS配置
[apim.gateway.cors]
allow_origins = ["https://frontendapp.mydomain"]
allow_methods = ["GET", "POST", "OPTIONS"]
allow_headers = ["authorization", "Content-Type"]
allow_credentials = true

3. 修正WSO2 IS的CORS配置

由于Token请求最终转发到IS,需添加APIM域名到允许列表:

[cors]
allow_generic_http_requests = true
allow_any_origin = false
allowed_origins = ["https://apim.mydomain", "https://frontendapp.mydomain"]
allow_subdomains = false
supported_methods = ["GET", "POST", "HEAD", "OPTIONS"]
support_any_header = true
supported_headers = ["authorization", "Content-Type"]
exposed_headers = ["Location", "authorization", "Content-Type"]
supports_credentials = true
max_age = 3600
tag_requests = false

4. 重启服务并验证

  1. 先重启WSO2 IS,再重启WSO2 APIM
  2. 用curl验证OPTIONS预检请求:
curl -X OPTIONS https://apim.mydomain/oauth2/token -H "Origin: https://frontendapp.mydomain" -H "Access-Control-Request-Method: POST" -v

检查响应头是否包含Access-Control-Allow-Origin、Access-Control-Allow-Credentials等字段。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 23:30:49