WSO2 ESB 的自动 NTLM 身份验证

Automatic NTLM Authentication for WSO2 ESB

我有一个 WCF Web 服务位于客户端的 IIS 服务器上,该服务器使用 NTLM 身份验证进行保护 - 我无法控制该服务器上的身份验证配置。

我需要将我的 WSO2 ESB 服务器与此服务集成,但我找不到让 ESB 自动进行身份验证的方法。我已成功通过 ESB 将请求推送到带有 Web 应用程序的服务,但系统提示我在该过程中提供我的 Windows 凭据 - 我希望这种情况不会发生。

我曾尝试在我的服务器上设置 NTLM 代理,但也无法解决这个问题。

任何指导将不胜感激。

紧张

好的,我找到了你的答案。如您所知,WSO2 ESB 将 Axis2 用于 Web 服务。您必须在 Axis2 配置文件 (ESB_HOME/repository/conf/axis2/axis2.xml).

中添加 NTLM 配置

此链接描述了配置。

http://wso2.com/library/161/

http://axis.apache.org/axis2/java/core/docs/http-transport.html

要使它正常工作,需要几个组成部分。很难找到所有内容都写在一个地方,所以我将尝试在这里提供一个端到端的概述。

我首先必须在我的 WSO2 ESB 中按顺序使用 class 调解器来处理发送 NTLM 身份验证。 class 中介引用自定义 class,它从中介流中获取消息上下文(称为 Synapse 消息上下文)并提取 SOAP 信封。然后我将 Synapse SOAP 信封加载到 Axis2 消息上下文对象中。然后,我使用 Axis2 客户端和消息上下文向服务器提交经过身份验证的请求。通过 Axis2 的 NTLM 身份验证来自 JCIFS_NTLMScheme class,您可以参考 here.

注意:您必须尝试使用​​ class 中的日志配置才能使其与 WSO2 一起使用。我刚刚删除了“org.sac.crosspather.common.util*”库并更改了我看到的任何日志记录以使用 Apache Commons 日志记录功能


在 WSO2 Developer Studio 中创建自定义调解器项目

在 Developer studio 中创建一个新项目。在项目浏览器中右击项目节点,select "New > Mediator Project".

这将为您生成一些样板代码 - 即 class 扩展 AbstractMediator 并实现 "mediate()" 方法,Synapse将在执行序列中定义的逻辑时调用。

public class NTLMAuthorisation extends AbstractMediator {

  public boolean mediate(MessageContext context){

    //Mediation Logic  

    return true;  

  }  

}


向用户公开一些 Variables/Properties

class 中介查找可公开访问的变量,并将它们公开在 WSO2 配置中。在您可以创建一个可重用的调解器之前,这很有用,调解器可以适应 WSO2 Carbon Web UI 中定义的属性或值。这里我们需要暴露七个变量:soapAction、SoapEndpoint、域、主机、端口、用户名和密码。通过定义实例变量及其访问器和修改器来公开变量。

这对于使用 WSO2 Secure Vault 存储您的 NTLM 密码并从具有属性的系统注册表中获取其他配置来说非常有用。

public class NTLMAuthorisation extends AbstractMediator { 

    private String soapAction;
    private String soapEndpoint;
    private String domain;
    private String host;
    private int port;
    private String username;
    private String password;

    public boolean mediate(MessageContext context) { 

        //Mediation Logic

        return true;

    }

    public void setSoapAction(String _soapAction){
        soapAction = _soapAction;
    }

    public String getSoapAction(){
        return soapAction;
    }

    public void setSoapEndpoint(String _soapEndpoint){
        soapEndpoint = _soapEndpoint;
    }

    public String getSoapEndpoint(){
        return soapEndpoint;
    }

    public void setDomain(String _domain){
        domain = _domain;
    }

    public String getDomain(){
        return domain;
    }

    public void setHost(String _host){
        host = _host;
    }

    public String getHost(){
        return host;
    }

    public void setPort(int _port){
        port = _port;
    }

    public int getPort(){
        return port;
    }

    public void setUsername(String _username){
        username = _username;
    }

    public String getUsername(){
        return username;
    }

    public void setPassword(String _password){
        password = _password;
    }

    public String getPassword(){
        return password;
    }

}


自定义中介逻辑

确保您从 here 创建了一个 JCIFS_NTLMScheme class 并已将 org.samba.jcifs 依赖项添加到您的 Maven 依赖项中,如下所示:

<dependency>
  <groupId>org.samba.jcifs</groupId>
  <artifactId>jcifs</artifactId>
  <version>1.3.17</version>
</dependency>

现在您可以在自定义调解器中使用以下调解方法class:

public boolean mediate(MessageContext context) { 

    //Build NTLM Authentication Scheme
    AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, JCIFS_NTLMScheme.class);
    HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
    auth.setUsername(username);
    auth.setPassword(password);
    auth.setDomain(domain);
    auth.setHost(host);
    auth.setPort(port);
    ArrayList<String> authPrefs = new ArrayList<String>();
    authPrefs.add(AuthPolicy.NTLM);
    auth.setAuthSchemes(authPrefs);

    //Force Authentication - failures will get caught in the catch block
    try {

        //Build ServiceClient and set Authorization Options
        ServiceClient serviceClient = new ServiceClient();
        Options options = new Options();
        options.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth);
        options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
        options.setTo(new EndpointReference(soapEndpoint));
        options.setAction(soapAction);
        serviceClient.setOptions(options);

        //Generate an OperationClient from the ServiceClient to execute the request
        OperationClient opClient = serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP);

        //Have to translate MsgCtx from Synapse to Axis2
        org.apache.axis2.context.MessageContext axisMsgCtx = new org.apache.axis2.context.MessageContext();  
        axisMsgCtx.setEnvelope(context.getEnvelope());
        opClient.addMessageContext(axisMsgCtx);

        //Send the request to the server
        opClient.execute(true);

        //Retrieve Result and replace mediation (synapse) context
        SOAPEnvelope result = opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE).getEnvelope();
        context.setEnvelope(result);

    } catch (AxisFault e) {

        context.setProperty("ResponseCode", e.getFaultCodeElement().getText());

        return false; //This stops the mediation flow, so I think it executes the fault sequence?

    }

    return true;

}


打包为 OSGi 包并部署到服务器

在此阶段,您应该能够在 WSO2 Developer Studio 的 项目浏览器 中以及从上下文菜单 select 中访问您的自定义调解器项目将项目导出为可部署存档。按照提示将 JAR 文件保存在系统的某个位置。生成JAR文件后,定位到[ESB_HOME]/repository/components/dropins目录下。您可能需要重新启动服务器才能检测到新的外部库。


使用自定义中介

在您的序列中,您现在应该能够添加 class mediator 并使用包名称和 class 名称一起引用您的自定义 class,例如:org.strainy.ntlmauthorisation.