WSO2 APIM集成IS时Token API的CORS错误求助
解决WSO2 APIM 4.x + IS 5.11.0 Token API CORS错误
问题分析
当前配置存在几个关键问题:
- 自定义Token API未处理OPTIONS预检请求,导致浏览器的预检请求无法得到正确的CORS响应头
- IS的CORS配置参数存在冲突,
allow_any_origin=true但allowed_origins=[]可能触发逻辑异常 - 自定义Token API的CORS Handler配置不完整,缺少凭证支持等必要参数
分步解决方案
1. 修正APIM自定义_TokenAPI_.xml配置
确保文件路径为 <APIM_HOME>/repository/deployment/server/synapse-configs/default/api/_TokenAPI_.xml(文件名需与跳过列表中的_TokenAPI_.xml完全一致,注意大小写),替换内容如下:
<?xml version="1.0" encoding="UTF-8"?> <api xmlns="http://ws.apache.org/ns/synapse" name="_WSO2AMTokenAPI_" context="/oauth2/token" binds-to="default"> <!-- 处理POST请求(实际Token获取) --> <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响应头,确保转发自IS的响应带上必要头 --> <property name="Access-Control-Allow-Origin" value="*" scope="transport"/> <property name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,PATCH,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"/> <send/> </outSequence> </resource> <!-- 专门处理OPTIONS预检请求 --> <resource methods="OPTIONS" binds-to="default" url-mapping="/*"> <inSequence> <property name="Access-Control-Allow-Origin" value="*" scope="transport"/> <property name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,PATCH,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"/> <property name="Access-Control-Max-Age" value="3600" scope="transport"/> <respond/> </inSequence> </resource> <handlers> <handler class="org.wso2.carbon.apimgt.gateway.handlers.common.SynapsePropertiesHandler"/> <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="*"/> <property name="allowedMethods" value="GET,PUT,POST,DELETE,PATCH,OPTIONS"/> <property name="allowCredentials" value="true"/> </handler> <handler class="org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerCacheExtensionHandler"/> </handlers> </api>
关键修改点:
- 添加独立的OPTIONS方法资源,直接返回预检响应,无需转发到IS
- 在POST请求的outSequence中显式添加CORS传输头,避免IS响应丢失头信息
- 调整Handler顺序,确保CORS Handler在Cache Handler之前执行
- 补充
allowCredentials参数,匹配前端凭证需求
2. 验证APIM同步跳过配置
确认deployment.toml中的跳过列表配置无误,重启APIM后检查<APIM_HOME>/repository/logs/wso2carbon.log,确认日志中出现:
INFO {org.apache.synapse.core.axis2.Axis2SynapseController} - Loaded API : _WSO2AMTokenAPI_
说明自定义API已成功加载。
3. 修正IS 5.11.0的CORS配置
更新<IS_HOME>/repository/conf/deployment.toml中的CORS配置,解决参数冲突:
[cors] allow_generic_http_requests = true allow_any_origin = true allowed_origins = ["*"] # 与allow_any_origin=true匹配,避免逻辑冲突 allow_subdomains = true 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
修改点:
- 将
allowed_origins设为["*"],与allow_any_origin=true保持一致 - 明确指定
supported_headers,避免默认过滤必要头 - 开启
allow_subdomains(如果前端域名是APIM/IS的子域名)
4. 重启服务并验证
- 重启WSO2 IS和APIM服务
- 用curl发送预检请求验证:
curl -X OPTIONS https://apim.mydomain/oauth2/token -H "Origin: https://frontendapp.mydomain" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: content-type" -v
检查响应头是否包含Access-Control-Allow-Origin、Access-Control-Allow-Methods等字段。
- 用Postman发送POST请求到Token API,确认响应头包含
Access-Control-Allow-Origin。
内容的提问来源于stack exchange,提问作者CKR
相关产品推荐
相关产品推荐

