【问题标题】:Access NTLM Secured WS Througth WSO2ESB通过 WSO2ESB 访问 NTLM 安全 WS
【发布时间】:2015-05-23 05:59:02
【问题描述】:

大家好,我正在尝试在 WSO2ESB 上设置代理服务以访问 NTLMv2 安全的 WS。我创建了一个中介类来实现这一点,但到目前为止还没有运气,我一直收到 401 状态

这里是代码。

代理服务:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="test"
       transports="http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target endpoint="fincasEP">
      <inSequence>
         <class name="com.aig.mediator.NTLMAuthMediator">
            <property name="port" value="remote-port"/>
            <property name="username" value="username-credential"/>
            <property name="host" value="remote-host-ip"/>
            <property name="domain" value="remot-host-domain"/>
            <property name="password" value="**********"/>
         </class>
      </inSequence>
   </target>
   <publishWSDL key="fincas-wsdl"/>
   <description/>
</proxy>

中介类:

public class NTLMAuthMediator extends AbstractMediator {

private String domain;
private String host;
private String port;
private String username;
private String password;

public boolean mediate(MessageContext context) {
    org.apache.axis2.context.MessageContext axis2MsgContext;


    axis2MsgContext = ((Axis2MessageContext) context).getAxis2MessageContext();
     String authString = (String)tmp.get("Authorization");

     HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
     setCredentials(auth);
     List<String> authSchemes = new ArrayList<String>();
     authSchemes.add(HttpTransportProperties.Authenticator.NTLM);
     auth.setAuthSchemes(authSchemes);
     auth.setPreemptiveAuthentication(true); // send authentication info at once
    Options options = new Options();
    options.setProperty(HTTPConstants.CHUNKED, "false");
    options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, "true");
    options.setProperty(HTTPConstants.AUTHENTICATE, auth);

    axis2MsgContext.setOptions(options);



    return true;
}

private void setCredentials(Authenticator auth) {

    boolean isDomain = this.domain != null ? true : this.domain.trim()
            .length() > 0 ? true : false;
    boolean isUsername = this.username != null ? true : this.username
            .trim().length() > 0 ? true : false;
    boolean isPassword = this.password != null ? true : this.password
            .trim().length() > 0 ? true : false;
    boolean isHost = this.host != null ? true
            : this.host.trim().length() > 0 ? true : false;
    boolean isPort = this.username != null ? true : this.username.trim()
            .length() > 0 ? true : false;

    if (!isDomain) {
        throw new RuntimeException("Domain parameter must NOT be null");
    }
    if (!isUsername) {
        throw new RuntimeException("Username parameter must NOT be null");
    }
    if (!isPassword) {
        throw new RuntimeException("Password parameter must NOT be null");
    }
    if (!isHost) {
        throw new RuntimeException("Host parameter must NOT be null");
    }
    if (!isPort) {
        throw new RuntimeException("Port parameter must NOT be null");
    }

    auth.setUsername(this.username);
    auth.setPassword(this.password);
    auth.setDomain(this.domain);
    auth.setRealm(AuthScope.ANY_REALM);
    auth.setHost(this.host);
    auth.setPort(Integer.valueOf(this.port));
    auth.setPreemptiveAuthentication(true);
}

public String getDomain() {
    return domain;
}

public void setDomain(String domain) {
    this.domain = domain;
}

public String getHost() {
    return host;
}

public void setHost(String host) {
    this.host = host;
}

public String getPort() {
    return port;
}

public void setPort(String port) {
    this.port = port;
}

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;
}

}

我正在使用 wso2esb 最新版本。

考虑到 NTLM 是一种旧机制,WSO2 没有为这种情况提供文档,这真的很令人沮丧。

任何建议都将不胜感激

顺便说一句,错误是:

401 - Unauthorized: Access is denied due to invalid credentials.

【问题讨论】:

    标签: java .net axis2 wso2esb synapse


    【解决方案1】:

    事实是,我终于可以使用 ESB Mule 解决这个问题了

    我正在查看有关 httpclient 的 NTLM 并在几个站点之后我注意到 httpclient 3.x 不支持这种类型的机制,这是因为它使用了 NTLMSchema。

    我发现了这个 git repo https://github.com/DovAmir/httpclientAuthHelper 这个人在编写与 httpclient 3.x 一起使用的 NTLMcuston shema 类方面做得很好,我克隆了这个 repo 生成了 jar 等,然后我修改了以下类

    org.apache.axis2.transport.http.AbstractHTTPSender
    ...
    ...
    ...
    protected void setAuthenticationInfo(HttpClient agent, MessageContext msgCtx, HostConfiguration config)
        throws AxisFault, UnknownHostException
      {
    String localhost = InetAddress.getLocalHost().getHostName().toUpperCase();
    ...
    ...
    if (domain != null) {
    
        creds = new NTCredentials(username, password, localhost, domain);
    } else {
        creds = new UsernamePasswordCredentials(username, password);
    }
        tmpHttpState.setCredentials(new AuthScope(host, port, realm), creds);
    }
    ...
    

    然后编写了一个测试用例,以确保axis2 ServerClient 确实有效.. 确实有效。但是...我想我并不真正了解 PassThroughHttpSender 的机制。 Aparently 还有其他事情要做,让它工作,我真的没有时间去做,然后我开始考虑其他事情,然后我意识到我们还有一个 ESB Mule 3.4.0 CE 实例正在运行.. .

    我只需要修改类

    HttpConnector
    {
    ...
    ...
    //    Properties added to enable NTLMv2 Auth
    
    private String ntlmUser;
    private String ntlmPassword;
    private String ntlmDomain;
    private String ntlmHost;
    private String ntlmPort;
    private boolean ntlmAuthentication;
    
    //getters and setters
    
        protected HttpClient doClientConnect() throws Exception
    {
        HttpState state = new HttpState();
        HttpClient client = new HttpClient();
        String localhost = InetAddress.getLocalHost().getHostName();
        //TODO setting domain as well.
        Credentials credentials;
    
        if (getProxyUsername() != null || getNtlmUser() != null)
        {
            if (isProxyNtlmAuthentication())
            {
                credentials = new NTCredentials(getProxyUsername(), getProxyPassword(), localhost, "");
                AuthScope authscope = new AuthScope(getProxyHostname(), getProxyPort());
                state.setProxyCredentials(authscope, credentials);
            }
            else if(isNtlmAuthentication()){
                AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, CustomNTLM2Scheme.class);
                AuthScope authscope = new AuthScope(getNtlmHost(), Integer.valueOf(getNtlmPort()));
                credentials = new NTCredentials(getNtlmUser(), getNtlmPassword(), localhost, getNtlmDomain());
                state.setCredentials(authscope, credentials);
            }
            else
            {
                credentials = new UsernamePasswordCredentials(getProxyUsername(), getProxyPassword());
                AuthScope authscope = new AuthScope(getProxyHostname(), getProxyPort());
                state.setProxyCredentials(authscope, credentials);
            }
    
        }
        client.setState(state);
        client.setHttpConnectionManager(getClientConnectionManager());
        return client;
    }
    

    这个流程是:

    <?xml version="1.0" encoding="UTF-8"?>
    <mule xmlns:http="http://www.mulesoft.org/schema/mule/http"          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" xmlns:pattern="http://www.mulesoft.org/schema/mule/pattern"
    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/pattern     http://www.mulesoft.org/schema/mule/pattern/current/mule-pattern.xsd">
    
    
    <http:connector name="ntlmconn"  
         doc:name="HTTP-HTTPS">
        <spring:property name="ntlmAuthentication" value="${ntlm.auth}"/>
        <spring:property name="ntlmUser" value="${ntlm.username}"/>
        <spring:property name="ntlmPassword" value="${ntlm.password}"/>
        <spring:property name="ntlmHost" value="${ntlm.host}"/>
        <spring:property name="ntlmPort" value="${ntlm.port}"/>
        <spring:property name="ntlmDomain" value="${ntlm.domain}"/>
    </http:connector>
    
    
    <pattern:web-service-proxy name="fincas-service"
        wsdlFile="${fincas.wsdl}">
        <http:inbound-endpoint address="http://localhost:8080/fincas" />
        <http:outbound-endpoint address="${endpoint}" connector-ref="ntlmconn"
             exchange-pattern="request-response"></http:outbound-endpoint>
    </pattern:web-service-proxy>
    

    最后,有了这个补丁,我可以让它工作了

    我希望它也对你有用。

    【讨论】:

      猜你喜欢
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多