Доступ к NTLM защищенному WS через WSO2ESB

1

Привет, ребята, я пытаюсь настроить прокси-службу на WSO2ESB для доступа к WSW NTLMv2. Я создал класс посредника для достижения этого, но пока не повезло, я продолжаю получать статус 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.

Это действительно разочаровывает, что WSO2 не предоставляет документацию для этого случая... принимая во внимание, что NTLM является старым механизмом.

Любое предложение было бы действительно оценено

Кстати, ошибка:

401 - Unauthorized: Access is denied due to invalid credentials.
Теги:
wso2esb
axis2
synapse

1 ответ

1
Лучший ответ

Правда в том, что я, наконец, смог решить эту проблему, используя ESB Mule, не говоря об этом, я собираюсь объяснить, как я пытался ее решить, используя WSO2ESB и, наконец, MULE...

Я смотрел, что происходит с NTLM в отношении httpclient, и после серверных сайтов я заметил, что httpclient 3.x не поддерживает этот тип механизма, и это потому, что он использует NTLMSchema.

Я нашел этот git repo https://github.com/DovAmir/httpclientAuthHelper, этот парень отлично справился с написанием класса Shema NTLMcuston, который работает с httpclient 3.x, я клонировал это репо, создавая банку и т.д. И т.д., После чего я изменил следующие класс

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

Затем написал тестовый пример, чтобы убедиться, что на самом деле работает serverClient axis2. И это произошло. НО... Я думаю, что я действительно не понимаю механизм PassThroughHttpSender. По-видимому, есть что-то еще, чтобы заставить его работать, у меня нет на это времени, а затем я начал думать о чем-то другом, а потом понял, что у нас также есть экземпляр 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>

Наконец, с этим патчем я могу заставить его работать. У меня развернута моя WS на ESB, и, поскольку служба запущена и работает, я могу потратить больше времени на поиск решения для WSO2ESB.

Надеюсь, это сработает и для вас.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню