gpt4 book ai didi

spring-boot - 通过 Spring Boot 调用 SOAP Web 服务失败并出现未经授权的 401 异常

转载 作者:行者123 更新时间:2023-12-02 04:27:48 26 4
gpt4 key购买 nike

我正在尝试通过 Spring Boot 应用程序调用安全的 SOAP Web 服务。

但是,当我尝试这样做时,尽管传递了所需的凭据,但我总是收到以下异常。

{
"timestamp": "2020-02-02T17:17:09.081+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Unauthorized [401]",
"trace": "org.springframework.ws.client.WebServiceTransportException: Unauthorized [401]\n\tat org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:699)\n\tat org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:609)\n\tat org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)\n\tat org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)\n\tat org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)\n\tat com.app.oracle.doo.ominvoker.client.SoapClient.createOrder(SoapClient.java:30)\n\tat com.app.oracle.doo.ominvoker.controller.OrderImportController.createOrder(OrderImportController.java:55)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.lang.reflect.Method.invoke(Method.java:498)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:660)\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:741)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598)\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n\tat java.lang.Thread.run(Thread.java:748)\n",
"path": "/createOrder"
}

我已经能够通过提供相同的凭据来通过 SOAP 工具调用相同的 Web 服务。我不确定传递 SOAP 头信息和调用 Web 服务的凭据的正确方法。

我引用了很多线程并找到了以下方法来实现它。然而,它对我来说仍然不起作用。

在这方面的任何帮助将不胜感激。

还有一点是,在通过soap工具调用服务时,我还将域信息设置为oracle/wss11_username_token_with_message_protection_client_policy。

我不知道如何传递此信息,因此将其设置为 Connection Request 中的属性之一(在 Authentication.java 文件中设置,如下所述)

谢谢

pom.xml

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.2</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<args>
<arg>-XautoNameResolution</arg>
</args>
<generatePackage>com.app.oracle.doo.ominvoker.soap.api.orderimport</generatePackage>
<generateDirectory>${project.basedir}/src/main/java</generateDirectory>
<schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
<schemaIncludes>
<include>*.wsdl</include>
</schemaIncludes>
</configuration>
</plugin>
</plugins>
</build>

SoapConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

import com.app.oracle.doo.ominvoker.client.SoapClient;

@Configuration
public class SoapConfig {

@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.app.oracle.doo.ominvoker.soap.api.orderimport");
return marshaller;
}

@Bean
public SoapClient orderImportClient(Jaxb2Marshaller marshaller) {
SoapClient client = new SoapClient();
client.setDefaultUri("https://host:port/order/OrderServices");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
client.setMessageSender(new Authentication("Manager", "Welcome1"));
return client;
}

}

SoapClient.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.stereotype.Service;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;

import com.app.oracle.doo.ominvoker.soap.api.orderimport.CreateOrders;
import com.app.oracle.doo.ominvoker.soap.api.orderimport.CreateOrdersResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service
public class SoapClient extends WebServiceGatewaySupport {

private static final Logger LOGGER = LoggerFactory.getLogger(SoapClient.class);

@Autowired
private Jaxb2Marshaller marshaller;

private WebServiceTemplate template;

public CreateOrdersResponse createOrder(CreateOrders request) {
template = new WebServiceTemplate(marshaller);
return (CreateOrdersResponse) template.marshalSendAndReceive("https://host:port/order/OrderServices", request);
}


}

身份验证.java

package com.app.oracle.doo.ominvoker.config;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.Base64;

import org.springframework.ws.transport.http.HttpUrlConnectionMessageSender;

public class Authentication extends HttpUrlConnectionMessageSender {

private String username;

private String password;

public Authentication() {
}

public Authentication(String username, String password) {
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
protected void prepareConnection(HttpURLConnection connection) throws IOException {
String userpassword = username+":"+password;
String encoded = Base64.getEncoder().withoutPadding().encodeToString(userpassword.getBytes());
connection.setRequestProperty("Authorization", "Basic " + encoded);
connection.setRequestProperty("domain", "oracle/wss11_username_token_with_message_protection_client_policy");
super.prepareConnection(connection);
}

}

最佳答案

您的 WS 不是由 WS-Security 保护的吗?而不是:HttpUrlConnectionMessageSender,您应该定义:org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor

@Bean
public Wss4jSecurityInterceptor securityInterceptor(){
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions("Timestamp UsernameToken");
wss4jSecurityInterceptor.setSecurementUsername("Manager");
wss4jSecurityInterceptor.setSecurementPassword("Welcome1");
return wss4jSecurityInterceptor;
}

然后将其注入(inject)到您的 Soap 客户端中:

    ClientInterceptor[] interceptors = new ClientInterceptor[] {securityInterceptor()};
client.setInterceptors(interceptors);

关于spring-boot - 通过 Spring Boot 调用 SOAP Web 服务失败并出现未经授权的 401 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60028677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com