使用NTLM与Wildfly进行HTTP响应'401:未授权'

时间:2018-01-23 20:17:22

标签: java sharepoint jboss jax-ws ntlm

当SOAP请求太长时,我们使用WildFly 11中的JAX-WS(引擎盖下的Apache CXF)作为响应获得'401: Unauthorized'

我们使用NTLM协议从WildFly调用SOAP Web服务。

如果请求大小很短,它可以正常工作,但如果请求是“大”(例如,带有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身份验证器:

private void authtWsSharepoint() throws Exception {
        Authenticator sAuthService = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("domain\\user", "password".toCharArray());
            }
        };
        Authenticator.setDefault(sAuthService);
    }

以下是例外:

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

1 个答案:

答案 0 :(得分:1)

魔术发生在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部署-structure.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>