访问NT​​LM担保WS Througth WSO2ESBLM、NT、WS、WSO2ESB

2023-09-04 00:49:08 作者:笑看人生

好家伙我试图安装一个代理服务上WSO2ESB访问NTLMv2的安全WS。我创建了一个中介类来实现这一点,但不是运气,到目前为止,我不断收到401状态

下面是code。

代理服务:

 < XML版本=1.0编码=UTF-8&GT?;
<代理的xmlns =htt​​p://ws.apache.org/ns/synapse
       NAME =测试
       运输=HTTP
       统计=禁用
       追溯=禁用
       startOnLoad =真正的>
   <目标端点=fincasEP>
      < inSequence中>
         <类名=com.aig.mediator.NTLMAuthMediator>
            <属性名=端口值=远程端口/>
            <属性名=用户名值=用户名-凭证/>
            <属性名=主机值=远程主机IP/>
            <属性名=域值=REMOT主机域/>
            <属性名=密码值=**********/>
         < /类>
      < / inSequence中>
   < /目标和GT;
   < publishWSDL键=FINCAS-WSDL/>
   <描述/>
< /代理>
 

中保类:

 公共类NTLMAuthMediator扩展AbstractMediator {

私人字符串域;
私人字符串主机;
私人字符串口;
私人字符串用户名;
私人字符串密码;

公共布尔中介(MessageContext的情况下){
    org.apache.axis2.context.MessageContext axis2MsgContext;


    axis2MsgContext =((Axis2MessageContext)上下文).getAxis2MessageContext();
     字符串authString =(字符串)tmp.get(授权);

     HttpTransportProperties.Authenticator AUTH =新HttpTransportProperties.Authenticator();
     setCredentials方法(AUTH);
     名单<字符串> authSchemes =新的ArrayList<字符串>();
     authSchemes.add(HttpTransportProperties.Authenticator.NTLM);
     auth.setAuthSchemes(authSchemes);
     auth.set preemptiveAuthentication(真正的); //发送验证信息一次
    选项​​选项=新的选项();
    options.setProperty(HTTPConstants.CHUNKED,假);
    options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT,真);
    options.setProperty(HTTPConstants.AUTHENTICATE,AUTH);

    axis2MsgContext.setOptions(选件);



    返回true;
}

私人无效setCredentials方法(验证AUTH){

    布尔isDomain = this.domain!= NULL?真:this.domain.trim()
            .length()> 0?真假;
    布尔isUsername = this.username!= NULL?真:this.username
            .trim()长度()> 0?真假;
    布尔isPassword = this.password!= NULL?真:this.password
            .trim()长度()> 0?真假;
    布尔isHost = this.host!= NULL?真正
            :this.host.trim()长度()> 0?真假;
    布尔isPort = this.username!= NULL?真:this.username.trim()
            .length()> 0?真假;

    如果(!isDomain){
        抛出新的RuntimeException(域参数不能为空);
    }
    如果(!isUsername){
        抛出新的RuntimeException(用户名参数不能为空);
    }
    如果(!isPassword){
        抛出新的RuntimeException(密码参数不能为空);
    }
    如果(!isHost){
        抛出新的RuntimeException(主机参数不能为空);
    }
    如果(!isPort){
        抛出新的RuntimeException(端口参数不能为空);
    }

    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.set preemptiveAuthentication(真正的);
}

公共字符串getDomain(){
    返回域;
}

公共无效setDomain(字符串域){
    this.domain =域;
}

公共字符串GETHOST(){
    返回主机;
}

公共无效setHost(String host)在{
    this.host =主机;
}

公共字符串的getPort(){
    返回端口;
}

公共无效setPort(串口){
    this.port =口;
}

公共字符串getUsername(){
    返回用户名;
}

公共无效setUsername(字符串username){
    this.username =用户名;
}

公共字符串getPassword来(){
    返回密码;
}

公共无效setPassword(字符串密码){
    this.password =密码;
}
 

}

I'm使用wso2esb最新版本。

It's很无奈WSO2没有为这种情况提供文件......考虑到NTLM是一个古老的机制。

任何建议将非常AP preciated

BTW的错误是:

  401  - 未经授权:访问由于凭据无效被拒绝。
 

解决方案

事实是,我终于可以使用ESB的骡子nontheless我要解释我是如何试图用WSO2ESB最后MULE解决了解决这个问题..

我看是用了就NTLM正在进行的HttpClient和serveral的网站后,我发现的HttpClient 3.x中不支持此类型的机制,这是因为NTLMSchema它使用了。

我发现这个混帐回购协议 https://github.com/DovAmir/httpclientAuthHelper 这家伙做了伟大的工作编写与HttpClient的3.x的工作原理NTLMcuston玛类,我克隆此回购协议产生的罐子等等等等,然​​后我修改了下面的类

  org.apache.axis2.transport.http.AbstractHTTPSender
...
...
...
保护无效setAuthenticationInfo(HttpClient的代理,一个MessageContext msgCtx,HostConfiguration配置)
    抛出AxisFault,UnknownHostException异常
  {
字符串本地主机= InetAddress.getLocalHost()的gethostname()与toUpperCase()。
...
...
如果(域!= NULL){

    creds =新NTCredentials(用户名,密码,本地主机,域名);
} 其他 {
    creds =新UsernamePasswordCredentials(用户名,密码);
}
    tmpHttpState.setCredentials(新AuthScope(主机,端口,境界),creds);
}
...
 

然后写了一个测试案例,以确保Axis2的ServerClient实际工作..它做到了。但是...我想我不真正了解PassThroughHttpSender的机制。 Aparently有其他事情做,使其工作,我真的没有时间了,然后我就开始想别的东西,然后我意识到,我们也有一个ESB骡子3.4.0 CE实例上运行..

我不得不修改了类

  HttpConnector
{
...
...
//属性添加到启用NTLMv2身份验证

私人字符串ntlmUser;
私人字符串ntlmPassword;
私人字符串ntlmDomain;
私人字符串ntlmHost;
私人字符串ntlmPort;
私人布尔ntlmAuthentication;

// getter和setter

    受保护的HttpClient doClientConnect()抛出异常
{
    的HttpState状态=新的HttpState();
    HttpClient的客户端=新的HttpClient();
    字符串本地主机= InetAddress.getLocalHost()的gethostname()。
    // TODO设置域为好。
    凭证凭证;

    如果(getProxyUsername()!= NULL || getNtlmUser()!= NULL)
    {
        如果(isProxyNtlmAuthentication())
        {
            凭据=新NTCredentials(getProxyUsername(),getProxyPassword(),本地主机,);
            AuthScope authscope =新AuthScope(getProxyHostname(),getProxyPort());
            state.setProxyCredentials(authscope,证书);
        }
        否则如果(isNtlmAuthentication()){
            AuthPolicy.registerAuthScheme(AuthPolicy.NTLM,CustomNTLM2Scheme.class);
            AuthScope authscope =新AuthScope(getNtlmHost(),Integer.valueOf(getNtlmPort()));
            凭据=新NTCredentials(getNtlmUser(),getNtlmPassword(),本地主机,getNtlmDomain());
            state.setCredentials(authscope,证书);
        }
        其他
        {
            凭证=新UsernamePasswordCredentials(getProxyUsername(),getProxyPassword());
            AuthScope authscope =新AuthScope(getProxyHostname(),getProxyPort());
            state.setProxyCredentials(authscope,证书);
        }

    }
    client.setState(州);
    client.setHttpConnectionManager(getClientConnectionManager());
    返回客户端;
}
 

的流量,这是:

 < XML版本=1.0编码=UTF-8&GT?;
<骡子的xmlns:HTTP =htt​​p://www.mulesoft.org/schema/mule/http的xmlns =htt​​p://www.mulesoft.org/schema/mule/core
的xmlns:DOC =htt​​p://www.mulesoft.org/schema/mule/documentation
的xmlns:春天=htt​​p://www.springframework.org/schema/beans版本=CE-3.4.0
的xmlns:XSI =htt​​p://www.w3.org/2001/XMLSchema-instance的xmlns:模式=htt​​p://www.mulesoft.org/schema/mule/pattern
XSI:的schemaLocation =htt​​p://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:连接器名称=ntlmconn
     DOC:NAME =HTTP,HTTPS>
    <春:属性名=ntlmAuthentication值=$ {ntlm.auth}/>
    <春:属性名=ntlmUser值=$ {ntlm.username}/>
    <春:属性名=ntlmPassword值=$ {ntlm.password}/>
    <春:属性名=ntlmHost值=$ {ntlm.host}/>
    <春:属性名=ntlmPort值=$ {ntlm.port}/>
    <春:属性名=ntlmDomain值=$ {ntlm.domain}/>
< / HTTP:连接器>


<图案:web服务代理的名称=FINCAS服务
    wsdlFile =$ {fincas.wsdl}>
    < HTTP:入站端点地址=HTTP://本地主机:8080 / FINCAS/>
    < HTTP:出站端点地址=$ {}端点连接器REF =ntlmconn
         交换模式=请求 - 响应>< / HTTP:出站端点>
< /模式:web服务代理>
 

最后这个补丁,我可以让它工作,我有我的WS部署在ESB和自服务启动并运行,我可以花更多的时间试图找到WSO2ESB一个解决方案。

我希望它适用于你。

Hello guys I'm trying to setup a proxy service on WSO2ESB to access a NTLMv2 secured WS. I created a mediator class to achieve this but not luck so far, I keep receiving 401 status

Here is the code.

Proxy Service:

<?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>

Mediator Class:

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

}

I´m using wso2esb lastest version.

It´s really frustrating WSO2 does not provide documentation for this case... taking into consideration that NTLM is an old mechanism.

Any suggestion would be really appreciated

BTW the error is:

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

解决方案

The truth is that I finally could solve this issue using ESB Mule nontheless I'm going to explain how I tried to solved it using WSO2ESB and finally MULE...

I was looking at was were going on with the NTLM regarding httpclient and after serveral sites I noticed that httpclient 3.x does not support this type of mechanism and It is because the NTLMSchema it uses.

I found this git repo https://github.com/DovAmir/httpclientAuthHelper this guy did a great job writing a NTLMcuston shema class that works with httpclient 3.x, I clone this repo generate the jar etc etc, then I modified the following class

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

Then wrote a test case to make sure that the axis2 ServerClient actually works.. and it did. BUT... I think I don´t really understand the mechanism of PassThroughHttpSender. Aparently there is something else to do, to make it work, I don't really have the time for it and then I started thinking on something else and then I realized that we also have an ESB Mule 3.4.0 CE instance running...

I just had to modified the class

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

The flow for this is:

<?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>

Finally with this patch I could make it work I have my WS deployed on the ESB and since the service is up and running I can spend more time trying to find a solution for WSO2ESB.

I hope It works for you as well.

 
精彩推荐
图片推荐