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

迁移Identity Server至v6.0.0后无法在Api Manager DevPortal添加沙箱OAuth2密钥

WSO2 AM 4.1.0 搭配 IS 6.0.0 无法添加沙箱OAuth2密钥问题解决

问题场景

  • WSO2 API Manager 4.1.0 搭配 Identity Server 5.11.0 时,可正常在DevPortal中添加沙箱OAuth2密钥;
  • 将Identity Server升级至6.0.0后,同版本AM 4.1.0无法完成该操作。

错误日志

TID: [-1234] [api/am/devportal] [2022-09-26 13:58:10,497] ERROR {org.wso2.carbon.apimgt.rest.api.util.exception.GlobalThrowableMapper} - An unknown exception
 has been captured by the global exception mapper. feign.codec.DecodeException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line
 19 column 1 path $                                                                                                                                          
        at feign.AsyncResponseHandler.decode(AsyncResponseHandler.java:119)                                                                                   
        at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:87)                                                                           
        at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138)                                                                
        at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)                                                                           
        at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)                                                                     
        at com.sun.proxy.$Proxy467.getApplication(Unknown Source)                                                                                             
        at org.wso2.carbon.apimgt.impl.AMDefaultKeyManagerImpl.mapOAuthApplication_aroundBody20(AMDefaultKeyManagerImpl.java:581)                             
        at org.wso2.carbon.apimgt.impl.AMDefaultKeyManagerImpl.mapOAuthApplication(AMDefaultKeyManagerImpl.java:561)                                          
        at org.wso2.carbon.apimgt.impl.APIConsumerImpl.mapExistingOAuthClient_aroundBody78(APIConsumerImpl.java:2517)                                         
        at org.wso2.carbon.apimgt.impl.APIConsumerImpl.mapExistingOAuthClient(APIConsumerImpl.java:2452)                                                      
        at org.wso2.carbon.apimgt.rest.api.store.v1.impl.ApplicationsApiServiceImpl.applicationsApplicationIdMapKeysPost(ApplicationsApiServiceImpl.java:1101
)                                                                                                                                                             
        at org.wso2.carbon.apimgt.rest.api.store.v1.ApplicationsApi.applicationsApplicationIdMapKeysPost(ApplicationsApi.java:281)                            
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)                                                                     
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)                                                   
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)                                           
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)                                                                                         
        at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179)                                                         
        at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)                                                                     
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201)                                                                                    
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104)                                                                                    
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)                                                      
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)                                              
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)                                                             
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)                                                       
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265)                                                     
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)                                                   
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)                                                              
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)                                                              
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225)                                                          
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:304)                                                   
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:217)                                                          
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)                                                                                       
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:279)                                                         
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)                                                  
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)                                                          
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)                                                                             
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)                                                  
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)                                                          
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)                                                                
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)                                                                 
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)                                                             
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)                                                                     
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)                                                                      
        at org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:107)                                
        at org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:110)                                                        
        at org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:102)                                                       
        at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:101)                                                       
        at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:49)                                                  
        at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)                                                                    
        at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:146)                                 
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)                                                          
        at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:58)                                              
        at org.wso2.carbon.tomcat.ext.valves.RequestCorrelationIdValve.invoke(RequestCorrelationIdValve.java:126)                                             
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)                                                                   
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)                                                                        
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)                                                                         
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)                                                                   
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)                                                            
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)                                                                
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)                                                                    
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)                                                          
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)                                                          
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)                                                                 
        at java.base/java.lang.Thread.run(Thread.java:829)                                                                                                    
Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 19 column 1 path $              
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)                                     
        at com.google.gson.Gson.fromJson(Gson.java:932)                                                                                                       
        at com.google.gson.Gson.fromJson(Gson.java:897)                                                                                                       
        at feign.gson.GsonDecoder.decode(GsonDecoder.java:50)                                                                                                 
        at feign.AsyncResponseHandler.decode(AsyncResponseHandler.java:115)                                                                                   
        ... 63 more                                                                                                                                          
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 19 column 1 path $                                                   
        at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:386)                                                                                 
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)                                     
        ... 67 more

问题分析

日志核心错误Expected BEGIN_OBJECT but was STRING表明:AM的Feign客户端调用IS的getApplication接口时,IS 6.0.0返回的JSON响应结构与AM 4.1.0预期格式不匹配。IS 6.0.0对OAuth应用相关API的响应结构做了调整,而AM 4.1.0的密钥管理器代码仍基于IS 5.x的响应格式解析,导致Gson反序列化失败,最终无法完成沙箱密钥的添加/映射。

解决方案

1. 安装官方兼容补丁

WSO2针对AM 4.1.0与IS 6.0.0的兼容性问题,发布了专门的密钥管理器适配补丁。下载对应补丁jar包后,放入AM的<AM_HOME>/repository/components/dropins目录,重启AM服务即可。

2. 自定义代码适配

若无法使用官方补丁,可手动修改AM侧密钥管理器的解析逻辑:

  • 找到org.wso2.carbon.apimgt.impl.AMDefaultKeyManagerImpl类的mapOAuthApplication方法
  • 调整Gson解析逻辑,兼容IS 6.0.0返回的新响应格式(如字段类型变更、字段增删等)
  • 重新编译该类并替换AM中的对应jar包

3. 临时绕过方案

若需快速恢复功能,可手动在IS 6.0.0中创建OAuth应用,获取客户端ID和密钥后,在AM DevPortal中手动将该应用映射到目标API应用,跳过自动创建/映射流程。

4. 配置验证

检查AM的deployment.toml中IS相关配置:

[apim.key_manager]
service_url = "https://<IS_HOST>:<IS_PORT>"
username = "<IS_SERVICE_ACCOUNT_USERNAME>"
password = "<IS_SERVICE_ACCOUNT_PASSWORD>"

确保配置的服务账号在IS 6.0.0中拥有Internal/application_mgt_view、Internal/application_mgt_update等必要权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:55:26