访问NTLM安全WS通过WSO2ESB

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

这是代码。

代理服务:

                

调解员类:

 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 authSchemes = new ArrayList(); 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是一种旧机制。

任何建议都会非常感激

BTW的错误是:

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

事实上,我终于可以使用ESB Mule来解决这个问题,但是我将解释我是如何尝试使用WSO2ESB解决它的,最后是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的机制。 显然还有别的事要做,让它工作,我没有时间去做它然后我开始考虑其他事情然后我意识到我们也有一个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; } 

这个流程是:

               

最后,通过这个补丁,我可以使它工作我在ESB上部署了我的WS,并且由于服务启动并运行,我可以花更多的时间来寻找WSO2ESB的解决方案。

我希望它对你也有用。