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://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.
我有一个 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://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.