需要配置的最后一个属性是objectDefinitionSource。这就是如何指定访问受保护的对象上不同方法所需要的认证。在这里,我们只想保护transferFunds()方法,并且只允许访问manager。通过列出所有符合条件的类名、方法名和进行访问所需的角色来实现:
com.mybank.bizlogic.AccountMgr.transferFunds=ROLE_MANAGER
定制的Axis处理程序
如先前所描述的,我们需要某个事物来连接Web service安全上下文和Acegi安全上下文。这里即用到定制的Axis处理程序AcegiBridgeAuthenticationHandler。我们保持了非常简单的实现,这样易于解释。可能引起注意的第一件事情是它实际上没有进行任何认证。我们只是从MessageContext中得到用户名和密码,然后照旧使用它们。当然,事实上真正的实现将尝试验证该信息。需要考虑的事情是真正的实现应该从SOAP消息中提取WS-Security头,然后进行处理以得到认证信息,而不是像我们这样仅仅从Axis MessageContext对象中提取他们。
得到认证信息后,接下来就是使其可用于Acegi。通过创建认证令牌,并在Acegi安全上下文中进行设置来实现。由于在进行用户名和密码认证,因此将创建UsernamePasswordAuthenticationToken的实例。进行创建前,需要指定为该主体授予了哪些权限。通过使用GrantedAuthority接口和称为GrantedAuthorityImpl的简单实现来实现。由于使用RoleVoter来进行访问决策,因此我们将进行授权的机构是角色。这里我们再次简化了实现,对其进行硬编码,授权主体manager角色,因为该角色是在POJO上调用transferFunds()方法所需要的。真正的实现可能将获取用户名和密码,然后在数据库或目录服务器中进行查找,以找到与该主体实际相关的角色。或者,在某些情况下,可在WS-Security头中以SAML声明形式获得该信息。
在任何情况下,一旦完成,都将创建UsernamePasswordAuthenticationToken实例,传递用户名、密码和授权的角色。通过使用这种形式的构造方法(采用GrantedAuthority数组),实际上在告知Acegi此令牌已经过了认证,因此不必再次进行认证。接下来,通过在SecurityContextHolder上
调用静态方法来得到SecurityContext,并将认证令牌设置到SecurityContext中。现在认证和角色信息对于Acegi是下游可用的,用于执行其安全检查。因此,我们已有效地将Web service安全上下文连接到Acegi安全上下文。
有几件需要考虑的其他事情。首先,Acegi还提供了非常可靠的认证能力,因此不是让Axis处理程序来关注认证,可以让Acegi做这些事情。若要这样做,使用未采用GrantedAuthority数组的构造方法来创建未经认证的认证令牌。用户还需要确保配置了适当的认证提供程序,而不是使用AnonymousAuthenticationProvider。第二,Acegi不仅支持用户名/密码认证,还支持其他认证。例如,如果在进行基于PKI的认证,用户可以使用X509AuthenticationToken,而不是UsernamePasswordAuthenticationToken。
最后,需要配置Axis,在服务的请求处理路径上包含该处理程序。通过向Axis配置文件deploy.wsdd和server-config.wsdd添加以下条目来实现:
use="literal">
结束语
关注点分离是开发面向服务的架构的关键原则。但是,它不仅需要应用到架构级,还需要应用到实现级。在本文中,我们演示了如何使用Axis、Spring和Acegi来实现符合SOA原则的受保护Web service。如示例代码所示,使用该方法使处理每个服务关注点的代码中的交叉依赖性减至最小。我们所给出的示例是刻意保持简单的,但应将其作为基础,用于开发具有可靠安全机制(结合了Web service安全性和Acegi提供的应用程序级安全性)的Web service。如前所述,真正的系统很可能需要开发处理程序,用来处理WS-Security头并将它们连接到Acegi安全上下文。一种方法是采用Apache工具包WSS4J,然后扩展其Axis处理程序以填充Acegi安全上下文,如本文所述。可能需要进行一些其他工作来创建捕获Acegi安全异常的Axis出站处理程序,并创建返回到客户端的更有意义的SOAP错误。
文章来源于领测软件测试网 https://www.ltesting.net/