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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 08:02:58