Quarkus集成Apache CXF调用SOAP WebService时,因HTTP2 Upgrade请求头触发403错误的解决咨询
Quarkus集成Apache CXF调用SOAP WebService时,因HTTP2 Upgrade请求头触发403错误的解决咨询
我在Quarkus应用里调用SOAP WebService时碰到了403错误,排查后发现请求里带了Connection: Upgrade, HTTP2-Settings头,怀疑是这个导致了服务端拒绝请求,想请教下怎么移除这个请求头。
错误日志
Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '403: (POST http://mydevelopserver/XISOAPAdapter/MessageServlet?senderParty=&senderService=hidden01&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=hidden2) 403' when communicating with http://mydevelopserver/XISOAPAdapter/MessageServlet?senderParty=&senderService=hidden01&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=hidden2 at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.doProcessResponseCode(HTTPConduit.java:1653) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1660) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1602) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1396) at org.apache.cxf.ext.logging.LoggingOutputStream.postClose(LoggingOutputStream.java:53) at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:228) at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:696) at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:528) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:439) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:354) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:312) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140) ... 39 more
背景与代码实现
我是通过Quarkus dev阶段自动生成WSDL对应的Java类(底层用的wsdl2java),服务需要基础认证,我做了如下配置:
认证类实现
import java.net.Authenticator; import java.net.PasswordAuthentication; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class WSDLAuthentication extends Authenticator { private String user; private String password; public WSDLAuthentication() { super(); // Config properties. this.user = "secret"; this.password = "secret"; Authenticator.setDefault(this); } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(this.user, this.password.toCharArray()); } }
WebService客户端类
@ApplicationScoped public class UserDataWebService { private Config config; private String MANDANTE; @CXFClient("maestroProveedoresService") private SISAPMaestroProveedoresSyncOut maestroProveedoresService; @Inject private ZprovsMapper zprovsMapper; public UserDataWebService() { // WSDL Auth. new WSDLAuthentication(); } public UserDataDTO getUserData(String userId) throws CustomException { ZFIMAESTROPROV zfimaestroprov = new ZFIMAESTROPROV(); zfimaestroprov.setPMANDANTE('100'); zfimaestroprov.setPTAXNUM('123456789'); try { // Excecute SOAP ws. ZFIMAESTROPROVResponse zfimaestroprovResponse = maestroProveedoresService .siSAPMaestroProveedoresSyncOut(zfimaestroprov); Optional<String> errorOptional = Optional.ofNullable(zfimaestroprovResponse.getPERROR()); switch (errorOptional.orElse(CustomTypes.EMPTY_FIELD.getLabel())) { case "E": System.err.println(CustomMessagesType.USER_NOT_FOUND.getLabel()); throw new CustomException(404, CustomMessagesType.USER_NOT_FOUND.getLabel()); default: ZPROVS userDataSAP = zfimaestroprovResponse.getSALIDA(); UserDataDTO userData = zprovsMapper.zprovsToUserDataDTO(userDataSAP); return userData; } } catch (jakarta.xml.ws.WebServiceException e) { e.printStackTrace(); throw new CustomException(503, CustomMessagesType.SERVER_UNAVAILABLE.getLabel()); } } }
我也在Quarkus配置文件里设置了基础认证,这个配置能正常获取WSDL定义。
请求日志与抓包分析
从请求日志能看到认证信息已经正确携带:
INFO [org.apa.cxf.ser.SI_.REQ_OUT] (executor-thread-1) REQ_OUT Address: http://mydeveloperservice/XISOAPAdapter/MessageServlet?senderParty=&senderService=hidden&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=hidden2 HttpMethod: POST Content-Type: text/xml ExchangeId: 1ce8c3ce-036f-4c87-b4d7-e94f2704ca73 ServiceName: SI_SAP_MaestroProveedores_sync_outService PortName: HTTPS_Port PortTypeName: SI_SAP_MaestroProveedores_sync_out Headers: {Authorization=Basic supperhidden, SOAPAction="http://sap.com/xi/WebService/soap1.1", Accept=*/*} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:ZFI_MAESTRO_PROV xmlns:ns2="urn:sap-com:document:sap:rfc:functions"><P_MANDANTE>100</P_MANDANTE><P_TAXNUM>123456789</P_TAXNUM></ns2:ZFI_MAESTRO_PROV></soap:Body></soap:Envelope>
用Wireshark抓包后,发现请求里包含了Connection: Upgrade, HTTP2-Settings头:
Hypertext Transfer Protocol POST /XISOAPAdapter/MessageServlet?senderParty=&senderService=hidden&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=hidden2 HTTP/1.1\r\n [ [truncated]Expert Info (Chat/Sequence): POST /XISOAPAdapter/MessageServlet?senderParty=&senderService=hidden&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=hidden2] [POST /XISOAPAdapter/MessageServlet?senderParty=&senderService=hidden&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=hidden2 HTTP/1.1\r\n] [Severity level: Chat] [Group: Sequence] Request Method: POST Request URI: /XISOAPAdapter/MessageServlet?senderParty=&senderService=hidden&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=hidden2 Request URI Path: /XISOAPAdapter/MessageServlet Request URI Query: senderParty=&senderService=hidden&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=hidden2 Request URI Query Parameter: senderParty= Request URI Query Parameter: senderService=hidden Request URI Query Parameter: receiverParty= Request URI Query Parameter: receiverService= Request URI Query Parameter: interface=SI_SAP_MaestroProveedores_sync_out Request URI Query Parameter: interfaceNamespace=hidden2 Request Version: HTTP/1.1 Connection: Upgrade, HTTP2-Settings\r\n Content-Length: 266\r\n [Content length: 266] Host: mydeveloperserverr\n HTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA\r\n Upgrade: h2c\r\n Accept: */*\r\n Authorization: Basic superhidden Content-Type: text/xml; charset=UTF-8\r\n SOAPAction: "http://sap.com/xi/WebService/soap1.1"\r\n User-Agent: Apache-CXF/4.0.1\r\n \r\n [Full request URI [truncated]: http://mydeveloperservice/XISOAPAdapter/MessageServlet?senderParty=&senderService=hidden&receiverParty=&receiverService=&interface=SI_SAP_MaestroProveedores_sync_out&interfaceNamespace=http:] [HTTP request 1/1] [Response in frame: 468] File Data: 266 bytes
我猜测就是这个请求头导致了服务端返回403错误。
环境栈
POM依赖配置
<properties> <compiler-plugin.version>3.11.0</compiler-plugin.version> <maven.compiler.release>17</maven.compiler.release> <org.mapstruct.version>1.5.5.Final</org.mapstruct.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id> <quarkus.platform.version>3.1.1.Final</quarkus.platform.version> <skipITs>true</skipITs> <surefire-plugin.version>3.0.0</surefire-plugin.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>${quarkus.platform.artifact-id}</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>quarkus-cxf-bom</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>quarkus-camel-bom</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>io.quarkiverse.cxf</groupId> <artifactId>quarkus-cxf</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-hibernate-orm</artifactId> </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-cxf-soap</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-hibernate-validator</artifactId> </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-soap</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-jdbc-oracle</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-arc</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-health</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-hibernate-orm-panache</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-jsonb</artifactId> </dependency> <dependency> <groupId>io.quarkiverse.cxf</groupId> <artifactId>quarkus-cxf-rt-ws-security</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.quarkiverse.cxf</groupId> <artifactId>quarkus-cxf-rt-features-logging</artifactId> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${org.mapstruct.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> <scope>provided</scope> </dependency> </dependencies>
服务端版本
SAP PI/PO 7.5
已尝试的操作
我搜了很多资料,想找到在Apache CXF里禁用Connection: Upgrade, HTTP2-Settings请求头的方法,但一直没找到有效的方案。
请问有没有办法让请求不携带这个头?
备注:内容来源于stack exchange,提问作者brunomaso1
相关产品推荐
相关产品推荐

