IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  WebSphere | SOA and Web services  >

使用 WID 6.2 和 WESB 6.2 实现动态服务网关模式

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

样例代码


级别: 中级

李 凌 (liling@cn.ibm.com), 软件架构师, IBM

2009 年 6 月 29 日

服务网关模式是 SOA 中实现松散耦合和访问安全的重要设计模式。本文详细介绍了在 WebSphere Integration Developer(WID)6.2 开发环境中实现动态服务网关模式的方法。在示例应用程序中,读者可以看到如何开发支持动态网关模式的中介流,并添加认证、授权、审计(AAA)等重要的功能,进一步强化服务网关在整个 SOA 架构中的重要作用。通过本文,读者还可以了解到 WebSphere Enterprise Service Bus(WESB)最新 6.2 版本的新特性。

SOA 的网关模式

在 SOA 架构设计中通常会引入服务网关这样一个软硬件实现,以作为企业内部服务的集中管控点。

服务网关可以完成下列核心功能:

  • 服务请求的路由,包括静态路由或动态路由,从而实现服务虚拟化;
  • 在不同的传输协议之间映射服务请求和响应,或在不同的数据格式、接口规范之间转换服务请求和响应;
  • 实现服务请求的访问控制(认证和授权)及审计。

这种融入了服务网关的 SOA 设计模式称为网关模式。在此模式中,服务网关作为服务生产者和消费者之间的服务中介,替换了传统实现模式中生产者和消费者直接交互的方式,如图 1 所示。网关模式体现了 SOA 的一些重要设计原则,例如:将服务消费者与服务的具体实现脱耦;将服务交互与其所依赖的实现技术相分离;集中治理企业内部的各个服务等等。


图 1. 网关模式
dynamic dateway




回页首


WebSphere ESB 对网关模式的支持

WebSphere Enterprise Service Bus(简称 WebSphere ESB 或 WESB)是 IBM 为企业级用户提供 Web 服务连通性和 JMS 消息传递的软件产品。它提供了基于标准的连接和集成解决方案,允许用户只需少量编程便能实现消息的格式转换、协议转换、寻址和路由,从而实现与任何 JMS 和 HTTP 应用程序的轻松集成。

当前 WebSphere ESB 的最新版本是 V6.2,该版本新加入了策略驱动的连接性支持(详见参考资源中的“中介策略模式”),可以从 IBM WebSphere Service Registry and Repository(简称 WSRR)中提取策略文件以驱动消息的处理;新增了 Type Filter、Data Handler 和 Header Setter 等中介原语,可以更便捷地构建中介流;此外,还强化了对最新 Web 服务标准的支持,包括 SOAP 1.2、JAX-WS 2.1 等等,可以构建新一代基于策略的 Web 服务。

WebSphere ESB 使用中介流(Mediation Flow)实现网关模式。在此模式中,请求消息首先被传入到中介流的输入节点,然后经过一系列中介流原语(Mediation Primitive)的处理之后,路由到目标服务;同样,响应消息也可以经过中介流的处理再路由到服务调用者。

在先前版本的 WESB 中,中介流只能实现静态网关模式,典型的实现方式是使用 Message Filter 中介原语根据事先定义的路由规则进行静态路由,如图 2 所示。静态网关模式中,服务请求到目标服务的映射是静态绑定的,每次变更都需要修改中介流模块,灵活性比较差。


图 2. 静态网关模式
dynamic dateway

WebSphere ESB V6.2 通过使用新的 Data Handler 和 Endpoint Lookup 中介原语来支持动态服务网关。Gateway Text Data Handler 和 Service Gateway Function Selector 使得网关仅使用一个统一的接口就能接入不同的服务。不同于在中介流中的硬编码分支和逻辑,Endpoint Lookup 中介原语使用外部的服务存储库来动态查找服务端点,从而实现服务信息的运行时动态绑定,如图 3 所示。外部的服务存储库可以是专业的 WSRR、普通的关系型数据库、甚至是简单的文件。如果某个服务的信息发生了更改,变更工作将在外部存储库中完成,不需要修改 WESB 上的中介流和网关接口,从而使得此实现成为动态的。

此外,由于采用的新的数据绑定方式,基于 WebSphere ESB V6.2 实现的服务网关可以使用 SOAP 1.2/HTTP、SOAP 1.1/HTTP、HTTP、JMS 或 MQ 作为传输协议。


图 3. 动态网关模式
dynamic dateway

本文的后续章节以 SOAP1.2 传输协议为例,详细介绍了动态服务网关的实现方式,有效地改进了 SOA 应用程序的运行时灵活性和连通性;并在该服务网关上实现了认证、授权和审计(AAA)功能,进一步强化服务网关在整个 SOA 架构中的重要作用。





回页首


构建动态服务网关框架

IBM WebSphere Integration Developer(简称 WID)是开发、调试和测试 SCA(Service Component Architecture)和中介流的集成开发环境。

本节将以 WID 6.2 为开发环境构建支持 SOAP1.2 协议的动态服务网关框架。这个动态网关可以根据请求消息中包含的服务名称到 WSRR 上搜索该服务的服务端点地址(Endpoint address),从而在运行时动态决定这个请求所要发送到的目标地址。服务名称信息将被包含在请求消息的 HTTP URL 中,例如 http://gateway_address/gateway?ServiceName=MyService。中介流可以从该 URL 中解析出服务名称为 MyService,进而查询 WSRR 得到该服务的真实地址为 http://test.com/MyService,最后把请求转发到目标服务。如图 4 所示。


图 4. 动态路由
dynamic dateway

实际上,搜索条件可以不局限于服务名称,也可以是服务版本、命名空间或任何自定义条件,这些条件还可以组合使用。考虑到性能因素,动态网关通常根据服务请求的上下文信息进行消息路由,而不会使用整个请求内容。在本例中,路由条件“服务名称”被放在 HTTP 请求头的 URL 后缀中,就是为了尽可能快地加速路由的处理过程,减少性能损耗。

首先,在 WID 中启动 Service Gateway 向导,File -> New -> Service Gateway,指定项目名称为 ServiceGateway,如图 5 所示,点击 Next 继续。


图 5. 指定项目名称
dynamic dateway

选择 Gateway 的类型为 Dynamic,以便创建一个动态网关,如图 6 所示。点击 Next。


图 6. 指定网关类型
dynamic dateway

在随后出现的“选择服务提供者”对话框中需要指定动态网关所使用的服务存储库类型,如图 7 所示,它可以是 WSRR、普通的数据库、或者是自己实现特定的处理逻辑等方式。这里选择 WSRR。其次,还可以指定是否进行服务请求和响应消息的记录,这里选择不记录,本文将在后续章节中介绍如何添加自定义的审计功能。点击 Next 继续。


图 7. 指定服务存储库
dynamic dateway

在图 8 所示菜单里选择网关使用的传输协议为 Web Service SOAP1.2/HTTP,表示网关所支持的服务类型是 JAX-WS Web 服务。SOAP1.1/HTTP 协议的网关适合处理 JAX-RPC Web 服务;HTTP 协议的网关适合处理普通的 Web 应用或者是 XML over HTTP 类型的 Web 服务;JMS 和 MQ 协议的网关则适合处理消息类型的应用。点击 Finish 完成创建。


图 8. 指定传输协议
dynamic dateway

切换到 Business Integration 视图,可以看到名为 ServiceGateway 的中介处理模块(Mediation Module)已经被创建。打开其中的装配图(图 9),可以看到图中包含 1 个 Export 组件,用于暴露网关所在的 JAX-WS 服务;1 个中介流组件,用于实现消息流转逻辑;和 1 个 Import 组件,用于调用后端的 JAX-WS 服务。


图 9. 装配图
dynamic dateway

Import 和 Export 组件均使用了 ServiceGateway 接口,该接口包含 2 个处理方法,如图 10 所示,其中 requestOnly 方法用于处理 One-way 方式的服务调用;requestResponse 方法用于处理 Request-and-Response 方式的服务调用,后续文章仅以 Request-and-Response 方式为例实现动态网关。可以看到,这两个方法的参数类型都是任意类型(anyType),这是因为网关要处理各种类型的服务请求。


图 10. 网关接口
dynamic dateway

双击 ServiceGateway 中介流模块,打开其具体实现,选中其中的 requestResponse 中介流,如图 11 所示。


图 11. Request Response 中介流
dynamic dateway

在 requestResponse 中介流中,选中 RouteMessage(Endpoint Lookup)原语,如图 12 所示,该原语以 WSRR 作为服务存储库,负责根据特定的条件(例如:服务名称)到 WSRR 中搜索指定服务的端点地址。


图 12. Endpoint Lookup 原语
dynamic dateway

为了实现动态网关的功能,在其 Properties -> Advanced -> User Properties 界面中添加端点搜索条件为 xPath 表达式 s ubstring-after(/headers/HTTPHeader/control/URL ,"?ServiceName=" ),如图 13 所示。该表达式用于从请求的 HTTP URL 参数中截取服务名称信息。


图 13. 搜索条件
dynamic dateway

由于本示例的动态网关使用了 WSRR 作为服务存储库,因此需要在测试 WESB/WPS 服务器上添加对 WSRR 的定义,并确保使用 6.2 或以上版本的 WSRR SOAP 接口,以便测试服务器可以正确访问 WSRR 服务存储库。同时,还需要将目标服务(Echo Web 服务)的 WSDL 和 XSD 文件导入到 WSRR 中,这两个文件可以从 EchoWS 工程中获取,测试服务(EchoWS)及其客户端(EchoClient)工程可从文章末尾的链接下载。

除了 WSRR 以外,动态网关还可以使用普通的数据库或者文件作为服务的存储库,使其在与第三方系统集成的时候具有很大的灵活性。





回页首


测试网关框架

为了测试网关框架的有效性,首先在 WID 中导入 Echo Web 服务的测试客户端 EchoClient 工程。该客户端能够向 Echo 服务发送一个“Hello world!”字符串,并显示调用的结果。由于要通过 Service Gateway 动态调用 Echo 服务,因此需要修改客户端发送 SOAP 请求的目的地址为动态网关的地址。打开 EchoClient -> META-INF -> wsdl -> EchoService.wsdl 文件,确保其中的 SOAP12 Address 元素如清单 1 所示。


清单 1. 访问地址
				
 <service name="EchoService">
 <port binding="tns:EchoPortBinding" name="EchoPort">
 <soap12:address location=
"http://localhost:9080/ServiceGatewayWeb/sca/ServiceGatewayExport?ServiceName=Echo"/>
 <!--<soap12:address location="http://localhost:9080/EchoWS/EchoService"/>-->
 </port>
 </service>

然后,将 ServiceGateway 模块发布到 WID 自带的 WESB 测试服务器上,并确保该模块被正确启动。最后,以 WebSphere Application Server V6.1 Application Client 的方式运行 EchoClient 工程,观察 Console 窗口,可以发现调用结果如清单 2 所示,说明网关正确地将服务请求路由到了目标服务,并返回了调用结果。


清单 2. 运行结果
				
Service invoking...
Service result: Hello world!





回页首


实现访问控制和审计

对于一个服务网关而言,它除了具备基本的服务请求的动态路由功能外,还需要具备认证、授权和审计(Authentication Authorization and Audit, AAA)功能,从而确保网关服务的安全性。本节将详细介绍这些功能在 Service Gateway 上的实现。

认证

认证(Authentication)是指对用户身份信息的鉴别,并仅对拥有合法身份的用户予以放行,是实现访问控制的基础。实现身份认证的方法有很多种,常见的包括用户名和口令认证、证书认证等。本节将介绍使用 HTTP Basic Authentication 实现身份认证的方法。

首先,在 Service Gateway 工程上点击右键,选择 Open Deployment Editor,打开中介流模块部署描述符。然后切换到 Exports 选项卡,在该选项卡中添加一个 Security Role,名称为 Authenticated。接着,为这个 Role 添加一个安全约束(Security Constraints),该约束定义了授权角色 Authenticated 所允许访问的 Web 资源集合,如图 14 所示。


图 14. Export 设置
dynamic dateway

接着,还需要为这个中介流模块配置允许访问的用户。切换到部署描述符的 Module 选项卡,在其中的 Security 选项点击 Gather 按钮,Authenticated 角色将自动被收集到 Security Roles 列表中;配置该角色所对应的 WebSphere Bindings 为 All authenticated users,如图 15 所示。


图 15. Security 设置
dynamic dateway

最后,保存并关闭模块部署描述符。以上配置完成了服务网关的认证功能,当未认证的用户访问服务网关时,将收到“HTTP 401 Unauthorized”异常信息。认证用户需要被添加到服务网关所在的 WESB 使用的用户注册库中(User Registry)。

授权

授权(Authorization)是指对已经通过身份验证的用户进行权限的赋予。被授权的用户只能执行自身权限所限定的行为。通过授权,可以实现多层次细粒度的访问控制。

本例中实现的授权模型,如图 16 所示,用户被映射到用户组(角色),用户组(角色)关联到授权访问的服务资源。该模型定义了哪些用户被允许访问哪些服务。这个授权模型以关系型数据库 Schema 的方式实例化,每个模型实体代表一个数据库表。这里以 DB2 为实现数据库,并在 WESB 测试服务器上配置了相应的 JDBC Provider 和 Data Source(jdbc/authorization)。


图 16. 授权模型
dynamic dateway

要实现网关的访问授权,首先在 WID 中打开 Service Gateway 工程,在其 Data Types 中添加一个 Business Object,命名为 RouteInfo,该 BO 包含了一个 String 类型的 URL 变量,用于保存从 HTTP 头中读取的请求 URL 信息,该信息包含了目标服务的名称。

接着打开 Service Gateway 中介流,为中介流添加两个消息处理原语,分别是 HTTP Header Setter 和 Custom Mediation,如图 17 所示。


图 17. 授权原语
dynamic dateway

打开其中 Get Service Name 原语的属性窗口,添加处理逻辑,如图 18 所示。它负责从服务请求的 HTTP 头中获取 URL,并拷贝到 SMO(Service Message Object)的变量 /context/transient/url 中。


图 18. 获取 HTTP URL
dynamic dateway

其次,在 Authorization 原语中添加访问授权处理逻辑,代码片段如清单 3 所示。这段代码首先从运行时上下文中获取已认证用户的登录信息,然后从 SMO 的 /context/transient/url 变量中获取该用户要访问的服务名称,最后调用 isAuthorized() 方法进行授权判断。


清单 3. 执行授权
				
String uid = "";
Context ctx = ContextManager.getContext();
Set<Principal> set = ctx.getRunAsSubject().getPrincipals();
for (Principal principal : set) {
 uid = principal.getName();
 uid = uid.substring(uid.lastIndexOf('/') + 1);
}
commonj.sdo.DataObject _smo = (commonj.sdo.DataObject)smo;
String url = _smo.getDataObject("context").getDataObject("transient").getString("url");
String serviceName=url.substring(url.indexOf("=")+1);
boolean isAuthorized=false;
isAuthorized=DAO.isAuthorized(uid,serviceName);
if(!isAuthorized)
 throw new ServiceBusinessException("Authorization failed!");
out.fire(_smo);

其中 DAO.isAuthorized() 方法访问授权数据库,并判断当前用户是否具有权限访问指定服务;如果授权通过则返回 True,否则抛出运行时异常“Authorization failed!”。关键代码片段如清单 4 所示。


清单 4. 授权方法的实现
				
public static DataSource ds = null;
public static Connection getDSConn() throws Exception {
 if (ds == null) {
 InitialContext nctx = new InitialContext();
 ds = (DataSource) javax.rmi.PortableRemoteObject.narrow(nctx
 .lookup("jdbc/authorization"), DataSource.class);
 }
 return ds.getConnection();
}
public static boolean isAuthorized(String user, String service) {
 boolean result = false;
 Connection conn = getDSConn();
 PreparedStatement pStQuery = conn
 .prepareStatement("select * from user, group, service where user.name='"
 + user + "' and service.name='" + service + "'");
 ResultSet rs = pStQuery.executeQuery();
 while (rs.next()) 
 result = true;
 pStQuery.close();
 conn.close();
 return result;
}

除了上述的实现以外,认证和授权的功能还需要底层服务器的支持,即服务网关所在的 WESB 服务器必须启用全局安全性(Global Security)以及应用程序安全性(Java EE Security)。

审计

审计是指对特定行为的记录,记录的内容通常包括行为的主体、行为的内容、行为发生的时间等等。

本节将介绍如何为服务网关添加服务请求和响应的审计功能。在消息中介流中可以方便地实现整个消息或者部分消息的审计,实现方式也有很多种,例如调用外部的审计服务将消息存入独立于网关之外的审计系统;或者直接将消息写入本地的文件或数据库系统。本节以消息日志原语为例实现消息的审计。

首先,在服务请求的中介流中添加一个消息记录原语(Message Logger Primitive),如图 19 所示。


图 19. 审计原语
dynamic dateway

默认情况下,该原语将消息的内容(Body)以 XML 的形式记录到指定的 JDBC 数据源中(jdbc/mediation/messageLog),在 WID 测试环境中,该数据源对应 WPS 内嵌的 Derby 数据库,数据库的 Schema 文件可以在 {Server_Install_Path}/dbscripts/EsbLoggerMediation 中找到。所记录的消息内容包括时间戳、消息 ID、中介原语名称、模块名称、消息对象(SMO)和对象的版本信息。可以在该原语的 Properties -> Details 菜单中改变这些设置。

同时,消息记录原语还支持自定义消息记录的格式和形式,例如写入到文本文件或操作系统日志。可以通过继承 Handler、Formatter 和 Filter 类来实现自定义审计,这些类是 Java 规范中的标准实现。

最后,可以用同样的方法在服务响应中介流中添加审计功能。

测试

测试之前首先确保测试服务器 WESB 与 WSRR 和授权数据库连接正常,再者确保 WESB 服务器所使用的 User Registry 中存在 Admin 和 User 这两个测试用户;并在授权数据库中添加如表 1 所示的授权信息。

1. 授权信息

User Group Service
Admin Administrators Echo
User Users Echo1

然后,打开测试客户端 Echo Client 的 Main 类,确保其中的用户名和密码信息为“Admin”。最后运行 Echo Client,发现调用成功,检查服务器日志可以得到以下运行结果。


清单 5. 授权结果
				
[4/20/09 20:42:49:375 CST] 0000005f SystemOut O User: admin
[4/20/09 20:42:49:375 CST] 0000005f SystemOut O Service Name: Echo
[4/20/09 20:42:49:375 CST] 0000005f SystemOut O Perform authorization...
[4/20/09 20:42:49:468 CST] 0000005f SystemOut O Authorization result: true

同时消息审计所使用的数据库表中会发现类似下面这条信息的记录。

29/04/09 21:11, 3E42W9K6-1209, Audit, Service Gateway, {Message Body}, 1

如果使用 User 用户来发起调用,虽然该用户在 User Registry 中存在,可以通过认证,但由于他未被授权访问 Echo 这个服务,因此会收到“Authorization failed!”运行时异常;如果使用未在 User Registry 中注册的用户或者已注册但未提供正确的口令,那么会收到认证失败的异常。





回页首


总结

服务网关模式作为 SOA 架构设计中常用的设计模式,具有脱耦服务消费者和服务提供者、集中管控和治理服务的优点。WebSphere ESB V6.2 提供了对动态网关模式的支持,并且支持包括 SOAP1.2/HTTP、SOAP1.1/HTTP、HTTP、JMS 和 MQ 在内的各种传输协议。本文以 SOAP1.2/HTTP 协议为例,构建了支持 JAX-WS 服务的动态服务网关。动态服务网关所需要集成的服务存储库可以是工业级标准的 WSRR,也可以是简单的关系型数据库。此外,本文还介绍了在动态服务网关上实现认证、授权和审计的方法,进一步强化了服务网关在整个 SOA 架构中的重要作用。






回页首


下载

描述名字大小下载方法
本文代码示例TestSuit.zip26 KBHTTP
关于下载方法的信息


参考资料

学习

获得产品和技术
  • 下载 IBM 产品评估版,获得来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。


关于作者

李凌,IBM 中国软件开发中心软件架构师,主要负责 WebSphere 相关产品的咨询、培训和实施工作;从2007年以来主要从事 SOA(Governance)解决方案咨询与实施工作;在 Web 服务、信息安全和 IP Multimedia Subsystem 领域有丰富的实践经验。




对本文的评价








IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款