Spring-WS调用SOAP服务添加Basic Authorization头返回401如何解决
问题根因
你当前的配置存在两个核心错误:
- 已定义
HttpComponentsMessageSenderBean,但未将它绑定到WebServiceTemplate上,你配置的用户名密码凭证完全没有生效 - 拦截器中手动添加的
username、password请求头不符合HTTP Basic Auth规范,标准Basic Auth的请求头为Authorization,值为Basic 用户名:密码的Base64编码结果
修复方案
方案1:绑定配置好的MessageSender(最推荐)
修改ticketDetailsClient的Bean定义,注入HttpComponentsMessageSender并绑定到内部的WebServiceTemplate即可:
@Bean @DependsOn({"marshaller", "httpComponentsMessageSender"}) public TicketDetailsClient ticketDetailsClient(Jaxb2Marshaller marshaller, HttpComponentsMessageSender messageSender) { System.out.println("BEAN CREATED: TICKETDETAILSCLIENT..."); TicketDetailsClient ticketDetailsClient = new TicketDetailsClient(); ticketDetailsClient.setDefaultUri("..."); // 替换为你的服务地址 ticketDetailsClient.setMarshaller(marshaller); ticketDetailsClient.setUnmarshaller(marshaller); // 新增这一行,绑定配置了凭证的消息发送器 ticketDetailsClient.getWebServiceTemplate().setMessageSender(messageSender); return ticketDetailsClient; }
该方案直接使用Spring WS原生的Basic Auth处理逻辑,不需要手动修改请求头,配置完成即可生效。
方案2:拦截器手动添加标准Basic Auth头(适合凭证需要动态调整的场景)
如果你需要在运行时动态切换用户名密码,可以直接修改拦截器代码,生成标准的Authorization请求头:
@Override public boolean handleRequest(MessageContext arg0) throws WebServiceClientException { TransportContext context = TransportContextHolder.getTransportContext(); HttpComponentsConnection connection =(HttpComponentsConnection) context.getConnection(); try { // 构造标准Basic Auth请求头 String authStr = "testu:test"; byte[] encodedAuth = java.util.Base64.getEncoder().encode(authStr.getBytes(java.nio.charset.StandardCharsets.UTF_8)); String authHeader = "Basic " + new String(encodedAuth); connection.addRequestHeader("Authorization", authHeader); } catch (IOException e) { e.printStackTrace(); } HttpLoggingUtils.logMessage("Client Request Message", arg0.getRequest()); return true; }
验证
配置完成后重新运行,请求头日志中会出现Authorization: Basic xxxxxx字段,401认证错误即可解决。
内容的提问来源于stack exchange,提问作者user2985193
相关产品推荐
相关产品推荐

