关注点分离(separation of concerns)是面向服务的架构(Service-Oriented Architectures,SOA)的核心原则。令人遗憾的是,该原则在实现SOA服务时常常起不到作用。我们通常会看到带有多个关注点(如安全、事务管理)的巨大的实现类,使用业务逻辑记录所有混合在一起的关注点。使用Spring Framework和Aspect Oriented Programming (AOP)原则,我们可以将关注点分离,以用于服务实现。
本文中我们将演示如何使用Apache Axis和Spring来开发Web service,并使用Acegi Security对其进行保护——同时保持关注点很好地分离。
动机和设计
本文中我们将使用的示例是名为FundsTransferService的服务,银行使用该服务将资金从一个账户转移到另一个账户。可以在本文的参考资料部分找到该服务的WSDL及所有源代码、配置文件和构建文件。我们有意让该服务保持非常简单,以便集中讨论本文更有意义的方面。在本服务的实现中,我们将涉及三个关注点:
·Web service管道,用来公开作为服务的功能
·用于转移资金的业务逻辑
·安全性,用于保证只有经授权的用户才能执行资金转移
而真正的系统很可能是必须处理其他的关注点,如事务管理、日志等。
我们想设计这样一种实现,处理每个关注点的代码与其他的代码完全分离。对于Web service管道,我们将使用Axis来公开作为服务的功能。用于将资金从一个账户转移到另一个账户的业务逻辑将封装在一组POJO(Plain Old Java Object)中。将通过Acegi Security框架来提供安全性。我们将使用Spring Framework及其AOP工具把各方面联系起来,使构成该Web service实现的所有代码之间的依赖性减到最小。
该实现的设计如图1所示。以黄色表示的对象就是我们需要实现的Web service。以蓝色表示的对象来自Axis;以粉红色表示的对象来自Acegi;以绿色表示的对象来自Spring。FundsTransferService是WSDL中所定义的服务接口。为了简化图表,我们将所有Axis类显示为名为Axis Engine的组件。BasicHandler也是Axis类,但由于它对于设计比较重要(稍后详述),所以单独显示出来。FundsTransferServiceSoapBindingImpl是Axis的生成类,需要实现它来提供服务功能。将直接通过Spring委派业务逻辑POJO AccountMgrImpl(稍后也会对此进行详细解释)。AccountMgrImpl与AccountMgr接口捆绑在一起是不错的做法,因为这样就允许我们插入Spring以发挥其作用(尽管有其他方法可以不带接口使用Spring)。
图1.FundsTransferService实现的设计
现在回到BasicHandler。需要返回的原因涉及到如何选择以提供安全。在本例中,将在两个不同级别上处理安全性:Web service的安全性,及应用程序代码的安全性,如POJO。按照关注点分离的理念,我们提出允许进行分离的设计。Axis允许插入定制的处理程序,侦听请求和响应消息,以提供其他功能(如安全性)。因此,我们将创建名为AcegiBridgeAuthenticationHandler的定制处理程序,负责处理Web service安全。将扩展Axis类BasicHandler,以便可以将其插入Axis处理程序框架。Acegi将用于提供应用程序级的安全,如提供对POJO的访问控制。
为了使这些方面无缝工作,需要将Web service安全上下文连接到Acegi安全上下文——因此定制的Axis处理程序类的名称为AcegiBridgeAuthenticationHandler。它不仅将处理Web service安全性,还负责将从该过程获取的安全上下文连接到Acegi环境,这样Acegi就可以决定是否授权访问POJO。方法是从Web service请求消息中提取安全声明,进行验证,然后创建认证令牌,因为我们已经为本例选择了用户名/密码认证,所以为UsernamePasswordAuthenticationToken。然后将该认证令牌设置到Acegi SecurityContext中,这样稍后在控制访问业务逻辑POJO时,Acegi可以使用请求方的证书和权限。
文章来源于领测软件测试网 https://www.ltesting.net/