使用mule esb调用.NET ASMX Web Service会抛出CXF异常:401未经授权。

3

我有一个.NET ASMX web服务在另一台服务器上,并且我已经在另一台服务器上安装了独立的Mule CE 3.4。我有一个非常简单的流程,需要调用这个.NET web服务并传递两个字符串参数。

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd">
    <custom-transformer returnClass="java.lang.String[]" mimeType="text/plain" class="com.rms.corpapps.utils.WebServiceParamsTransformer" name="Java" doc:name="Java"/>
<http:connector name="httpConnector" enableCookies="true" proxyHostname="myserver" proxyUsername="domain\myusername" proxyPassword="mypassword" proxyPort="80" >
    <spring:property name="proxyNtlmAuthentication" value="true"/>
</http:connector>
<flow name="sftestFlow1" doc:name="sftestFlow1">
    <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" path="flows/sftest"/>
    <custom-transformer class="com.mycompany.utils.WebServiceParamsTransformer" doc:name="Transform Data for web service" doc:description="This java component prepares the input for web service"/>
    <cxf:jaxws-client doc:name="SOAP"
        clientClass="com.mycompany.WebServiceListener" port="WebServiceListenerSoap"  operation="ProcessExternalMessage"
    />
    <outbound-endpoint address="http://myserver/sm/webservicelistener.asmx?wsdl" doc:name="Generic" exchange-pattern="request-response" connector-ref="httpConnector"/>
</flow>

基本上,我正在暴露一个http入站端点(用于测试目的)来调用流程,并使用一个Java转换器类,该类返回需要传递到Web服务的字符串。 以下是WebServiceParamsTransformer类的代码。
public class WebServiceParamsTransformer extends AbstractTransformer {
    @Override
    public Object doTransform(Object src, String encoding) throws TransformerException {
        Object[] out = new Object[2];
    out[0] = "Update Ticket Service";
    out[1] = Base64.encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><event source=\"SHUB\" target=\"TP\" type=\"SUB8\" version=\"1.0\" timestamp=\"2013-09-16T15:52:14.0000+00.00\"><new-eta-event><incident-number>123456</incident-number><user-name>hari</user-name><eta-timestamp>2013-09-16T15:52:14.0000+00.00</eta-timestamp></new-eta-event></event>");

    return out;
    }
}

很遗憾,这个不起作用 - 我收到以下错误 'Response code: 401. Unauthorized'。这是错误日志的摘录:
INFO  2013-09-17 13:54:13,396 [[sftest].httpConnector.receiver.02] org.apache.commons.httpclient.auth.AuthChallengeProcessor: **ntlm authentication scheme selected**
INFO  2013-09-17 13:54:13,397 [[sftest].httpConnector.receiver.02] org.apache.commons.httpclient.HttpMethodDirector: **No credentials available for NTLM <any realm>@myserver:80**
INFO  2013-09-17 13:54:13,397 [[sftest].httpConnector.receiver.02] org.mule.transport.http.HttpClientMessageDispatcher: **Received a redirect, but followRedirects=false. Response code: 401 Unauthorized**
WARN  2013-09-17 13:54:13,398 [[sftest].httpConnector.receiver.02] org.apache.cxf.phase.PhaseInterceptorChain: Interceptor for {http://tempuri.org/}WebServiceListener#{http://tempuri.org/}ProcessExternalMessage has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Response was of unexpected text/html ContentType.  Incoming portion of HTML stream: **You do not have permission to view this directory or page.**

.NET web服务受到Windows集成身份验证保护,运行在.NET Framework 2.0下的 Windows Server 2008中的IIS 7中。以下是显示认证设置的截图。 enter image description here 我做错了什么?我的要求是从驴骡ESB简单地调用一个受集成身份验证保护的Web服务。任何帮助都将不胜感激。
1个回答

2

这是由于认证异常引起的。

<cxf:jaxws-client operation="Get_Workers"
            clientClass="com.saba.workday.ws.human_resources.HumanResourcesService"
            port="Human_Resources" wsdlLocation="classpath:Human_Resources.wsdl"
            doc:name="Get_Workers">
            <cxf:outInterceptors>
                <spring:ref bean="CredentialsSupplierBean" />
            </cxf:outInterceptors>
        </cxf:jaxws-client>

这里的Credential Supplier是一个扩展了WSS4JOutInterceptor的bean,用于进行身份验证。

Credential Supplier:

public class CredentialsSupplier extends WSS4JOutInterceptor {

 public CredentialsSupplier() {
    setProperty("action", "UsernameToken");
    setProperty("passwordType", "PasswordText");
 }

    @Override
    public void handleMessage(SoapMessage message) {
        super.handleMessage(prepareHandleMessage(message));
    }

    protected SoapMessage prepareHandleMessage(SoapMessage message) {
            message.setContextualProperty("user", "username");
            message.setContextualProperty("password", "pswd");
        return message;
    }
}

我理解这是一个身份验证异常。你有没有完整的示例或参考,关于如何调用.NET Web服务,该服务由集成认证保护?我已经搜索了很多,但迄今为止没有运气。在你上面引用的示例中,我相信CredentialsSupplierBean是一个Java类。你能发布那个代码吗?(自从我工作在Java上已经很长时间了)。 - Tech Matrix
不幸的是,这也没有起作用。我对错误信息有点困惑。当我查看日志时,首先看到以下错误:org.apache.cxf.binding.soap.SoapFault: 未定义安全操作。接着,我看到了之前的错误消息:org.apache.cxf.interceptor.Fault: 响应的ContentType意外为text/html。HTML流的传入部分为:您无权查看此目录或页面。有什么想法吗? - Tech Matrix
我已经编辑了我的答案,在构造函数中添加了 setproperty。它设置了 action 值,当我第一次粘贴代码时,我删除了很多代码,因此错过了这个。源代码链接搜索" No security action was defined",你会看到没有设置 action 值。 - Anil Puliyeril

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接