当 SOAP 请求太长时,我们将使用 WildFly 11 中的 JAX-WS(后台的 Apache CXF)获得'401: Unauthorized'
作为响应。
我们正在使用 NTLM 协议(protocol)从 WildFly 调用 SOAP Web 服务到 SharePoint。
如果请求大小较短,则可以正常工作,但如果请求“较大”(例如 1MB 的 SOAP 消息),则会失败并显示错误 HTTP 401。我们正在使用此 Web 服务发送图像,但编码为 base64二进制。
我们尝试使用 SOAP UI 调用该服务并且它有效,因此这似乎是应用程序服务器中的问题。可能发生什么情况,我们可以使用哪些解决方法?
更新: Jira 问题 CXF-5890好像和这个有点相似。
我们的客户端代码非常简单,我们发送一个 BASE64 字节数组(s:base64Binary):
@Stateless
public class Client {
@WebServiceRef(wsdlLocation = "/wsdl/service.wsdl")
private ServiceRepository service;
public void send() {
Repository repository = service.getRepositorySoap();
Map<String, Object> requestContext = ((BindingProvider) repository).getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://customerendpoint/service.asmx");
// sets standard Java authentication for NTLM
authtWsSharepoint();
// This method loads an image in BASE64. We found the problem around 45,000 characters, but it is not exact
String image = getImage();
repository.submitFile(image.getBytes());
}
}
我们正在使用标准 Java 身份 validator :
private void authtWsSharepoint() throws Exception {
Authenticator sAuthService = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("domain\\user", "password".toCharArray());
}
};
Authenticator.setDefault(sAuthService);
}
这是一个异常(exception):
Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '401: Unauthorized' when communicating with http://customerendpoint/service.asmx
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1581)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1533)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1336)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:215)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:652)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:138)
... 110 more
最佳答案
神奇的事情发生在httpClientPolicy.setAllowChunking(false)
。将其设置为 false 解决了问题。
代码示例
Client client = ClientProxy.getClient(servicePort);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
//This is the magic line. Setting this to false solved the problem
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
依赖关系
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>3.0.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.0.5</version>
<scope>provided</scope>
</dependency>
jboss-deployment-struct.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.apache.cxf.impl">
<imports>
<include path="META-INF"/>
<include path="META-INF/cxf"/>
</imports>
</module>
</dependencies>
</deployment>
</jboss-deployment-structure>
关于java - 使用 NTLM 和 Wildfly 的 HTTP 响应 '401: Unauthorized',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48410111/