内容


在 WebSphere Application Server V7 上通过 JAX-WS 实现消息级安全性

集成 JEE 授权

系列内容:

此内容是该系列 # 部分中的第 # 部分: 在 WebSphere Application Server V7 上通过 JAX-WS 实现消息级安全性

敬请期待该系列的后续内容。

此内容是该系列的一部分:在 WebSphere Application Server V7 上通过 JAX-WS 实现消息级安全性

敬请期待该系列的后续内容。

简介

Web Services Security (WS-Security) 是一种描述如何对 Web 服务实现消息级安全性的 OASIS 标准。具体来讲,WS-Security 描述如何实现机密性(例如加密)、完整性(例如数字签名)并在 SOAP 消息中传播用于身份验证的安全令牌(token)(例如用户名和密码)。然而,WS-Security 允许在 SOAP 消息中同时发送多个安全令牌,并且典型的 Java™ Platform, Enterprise Edition (JEE) Web 服务提供者实现根据来自其中一个安全令牌的 principal(身份)执行授权检查。在本文中,我们将描述如何配置 WebSphere 来选择 SOAP 消息的安全令牌作为 JEE principal,后者可用于作出授权决策。

注意,JEE 安全模型对 Web 容器和 EJB 容器支持声明式安全授权以及编程安全性。使用 Web 容器编程 API(比如 getUserPrincipal())和使用 EJB 容器编程 API(比如 getCallerPrincipal())之间存在着细微的差别。然而,本文的内容是讨论如何配置 Web 服务以将 SOAP 头部中的其中一个令牌指定为 JEE principal。一旦对这个 principal 进行了设置,您就可以像往常那样使用 JEE 安全模型和 WebSphere Base Security API。

您可以通过声明或编程的方式对 servlet 和 EJB 使用 JEE 安全模型以实现授权。然而,考虑到本文的意图,我们将演示一个基于 servlet 的 Web 服务,它将使用编程式 JEE API 获得 principal。您可以对样例进行扩展以使用 JEE 编程式 API 来对基于 servlet 的基础 Web 服务提供者执行编程式授权检查,或者为 EJB 配置基于角色的 JEE 消息级安全性。针对 web 容器以及 EJB 容器的 JEE 声明式和编程安全性已在其他资料中加以介绍,因此不会作为本文的重点。(参见 参考资料 获得更多信息)。我们的目标是演示如何支持消息级安全令牌的集成,以在 WebSphere Application Server 上结合使用 JEE 授权框架。

创建一个 JAX-WS 服务提供者

  1. 使用 Rational Application Developer (Application Developer) V7.5.2,创建一个新的动态 Web 项目,项目名为 HelloWorldProject
  2. 接下来,使用 HelloWorldProvider 作为名称创建一个新的 Java 类,并将清单 1 的内容复制到这个新类。
    清单 1. HelloWorldProvider.java
     package com.ibm.dwexample;
                                import javax.annotation.Resource;
                                import javax.jws.WebService;
                                import javax.xml.ws.WebServiceContext; 
                                @WebService public class
                            HelloWorldProvider { @Resource WebServiceContext wsCtx;
                             public
                            String sayHello(String msg) { System.out.println("[provider]
                            received " + msg); System.out.println("[provider] user = " +
                            wsCtx.getUserPrincipal()); return "Hello " + msg; } }

    HelloWorldProvider 代码中比较有趣的部分是 @Resource WebServiceContext。这行代码允许 JAX-WS 运行时注入 Web 服务上下文并使您能够从该上下文访问 JEE principal。然而,为了使代码在 Application Server 中实际返回正确的 principal,您必须在服务提供者绑定中配置 Caller;否则,结果可能会是 “Principal: /UNAUTHENTICATED*quot;”。

  3. 右键单击 HelloWorldProject 并选择 Run As => Run on Server。确保选中 Publishing settings for WebSphere Application Server 区段中的 Run server with resources on Server
  4. 选择 WebSphere Application Server v7.0 服务器概要文件并单击 Finish

为服务提供者提供安全性

策略集和策略集绑定已在 第 1 部分 中介绍,因此我们将直接创建一个策略集,使用它为 Web 服务指定一个 UsernameToken 作为身份验证令牌。当创建好策略集并将其附加到服务提供者后,您将创建一个服务器端绑定,在其中指定将用作主安全令牌的令牌 —— 即 JEE principal。这样做的原因是因为 WS-Security 规范允许为身份验证附加多个令牌,这样就需要更多的元数据来识别哪一个是主安全令牌。在 WebSphere 中,这些元数据称作 Caller 并被配置为 WS-Security 绑定的一部分,本文将展示这一点。

我们将使用 Application Server 管理控制台创建策略集并将其附加到您的服务提供者,然后创建一个绑定,服务提供者将通过该绑定遵守策略。

  1. 从 Application Developer 中,右键单击 Servers 视图中的 Application Server V7 运行时并选择 Administration => Run administrative console,如图 1 所示。
    图 1. 启动管理控制台
    启动管理控制台
    启动管理控制台
  2. 从管理控制台中,选择 Services => Policy sets => Application policy sets,如图 2 所示。
    图 2. 应用程序策略集
    应用程序策略集
    应用程序策略集
  3. 单击 New 创建一个新策略集。
  4. 指定 My UNT 作为新策略集的名称并在 Description 字段中添加描述,然后单击 Apply
  5. 接下来单击 Policies 区段中的 Add 并选择 WS-Security 作为将要添加的策略,如图 3 所示。
    图 3. 新策略集
    新策略集
    新策略集
  6. 将策略添加到您的新策略集后,只需单击 WS-Security 即可配置它。
  7. 单击 Main policy;您应当看到如图 4 所示的画面。
    图 4. 配置 WS-Security 策略
    配置                     WS-Security 策略
    配置 WS-Security 策略
  8. 默认情况下,WS-Security 策略在创建时使用了消息级别的保护,如 第 1 部分 所述。然而,为了使事情简单一些,本文将禁用消息级保护,方法是取消选中 Message level protection,然后单击 Apply
  9. 由于我们的策略需要一个 UsernameToken 来提取 JEE principal,因此您需要将 UsernameToken 添加到 WS-Security 策略,执行以下操作:
    1. 在 Main Policy 中,单击 Policy Details 区段中的 Request token policies
    2. 单击 Add Token Type 并选择 UserName,如图 5 所示。
    图 5. 将 UsernameToken 添加到 Request Token 策略
    将 UsernameToken 添加到 Request Token                     策略
    将 UsernameToken 添加到 Request Token 策略
  10. 指定 MyUsernameToken 作为 Username token,选择 WS-Security 1.0 作为 WS-Security 版本,如图 6 所示,然后单击 Apply
    图 6. 指定 UsernameToken
    指定 UsernameToken
    指定 UsernameToken
  11. 单击 Save,将更改直接保存到主配置。您应当会看到如图 7 所示的画面。
    图 7. 已配置的 UsernameToken 策略
    已配置的 UsernameToken 策略
    已配置的 UsernameToken 策略
  12. 现在策略集已经创建,您需要将其附加到服务提供者。从管理控制台中,选择 Services => Service providers 来获得 JAX-WS 服务提供者的列表,然后选择 HelloWorldProviderService,如图 8 所示。
    图 8. JAX-WS 服务提供者
    JAX-WS 服务提供者
    JAX-WS 服务提供者
  13. 选中 HelloWorldProviderService,单击 Attach Policy Set,然后选择您的策略集(例如 My UNT)。
  14. My UNT 策略集现在被附加到 HelloWorldProviderService,如图 9 所示。
    图 9. 将策略集附加到服务提供者
    将策略集附加到服务提供者
    将策略集附加到服务提供者
  15. 策略集指定了 “内容”,而绑定则指定了 “方式”。因此,您需要为这个服务提供者配置策略集绑定。为此,执行以下操作:
    1. 选中 HelloWorldProviderService,然后单击 Assign Binding 并选择 New Application Specific Binding
    2. 指定 ServerUNTBinding 作为 Bindings configuration name,然后单击 Add 并选择 WS-Security 以创建特定于应用程序的绑定,如图 10 所示。
      图 10. 策略集绑定配置
      策略集绑定配置
      策略集绑定配置

      注意,绑定分配将检查策略集以确定需要对哪些策略进行配置。在本文中,策略集包含了一个 WS-Security 策略,这也是该策略被包含到 Add 下拉菜单中的原因。

  16. 由于您添加到服务提供者中的 WS-Security 策略集包含 UsernameToken 作为必需的请求者令牌,您需要执行以下步骤以在绑定中为该策略指定 “方式”:
    1. 通过单击 Authentication and protection 显示 ServerUNTBinding 的细节
    2. 导航到身份验证令牌部分并单击 request:MyUsernameToken。您应当会看到如图 11 所示的画面。
      图 11. UsernameToken 身份
      UsernameToken 身份
      UsernameToken 身份
    3. 为该场景保留默认值,然后单击 OK
  17. 根据 WS-Security 规范,您现在已经将在 SOAP 头部传递的 UsernameToken 指定为供服务提供者使用的身份验证令牌。然而,注意 WS-Security 规范允许在请求消息中传递多个令牌,因此您将需要向 WebSphere 指定使用哪些令牌创建 WebSphere 凭证(即 JEE 对象),这样特定令牌的身份就可以用于 JEE 安全性,比如基于角色的授权检查。在 WebSphere 中,这是通过按如下方式配置调用方实现的:
    1. 从 Callers 对话框中单击 Caller(参见 图 10),然后单击 New
    2. 输入 Caller 作为 Name
    3. Caller identity local part 输入
      http://docs.oasis-open.org/wss/2004/01
      /oasis-200401-wss-username-token-profile-1.0#UsernameToken

      ,如图 12 所示。注意此 URL 是 图 11 所示的身份验证令牌的 Local part 的值。
      图 12. 指定调用方
      指定调用方
      指定调用方
    4. 单击 OK 接受该调用方,然后单击 Save,将绑定保存到主配置中。

使用安全服务

要确保服务使用者遵循服务提供者的策略,最简单的方法也许就是使用相同的策略集。具体操作就是从 Application Server 管理控制台导出服务提供者策略集,然后将其导入到 Application Developer。

要导出策略集,执行下面的步骤:

  1. 从管理控制台中,选择 Services => Policy sets => Application policy sets
  2. 选中 My UNT 策略集,然后单击 Export =>,如图 13 所示。
    图 13. 导出策略集
    导出策略集
    导出策略集
  3. 单击 MyUNT.zip 并将文件保存到本地驱动中的某个位置;例如,c:\temp。
  4. 单击 OK 保存文件。

要将策略集导入到 Application Developer,执行下面的操作:

  1. 从 Application Developer 主菜单中,选择 File => Import => Web services => WebSphere Policy Sets ,然后单击 Next
  2. 单击 Browse 并选择您前面导出的 MyUNT.zip 文件。向导将读取 zip 文件并显示其中包含的策略集,如图 14 所示。
    图 14. 导入策略集
    导入策略集
    导入策略集
  3. 确保选中 MyUNT 并单击 Finish

现在您已经将策略集导入到 Application Developer 中,您需要创建一个服务使用者客户机,以将策略集附加到其上:

  1. 在 Application Developer 中,选择 File => New => Other => Java => Java Project 创建一个新的 Java 项目来保存使用者。
  2. 指定 HelloWorldConsumer 作为 Client project name,然后单击 Finish。如果出现要您切换到 Java 透视图的提示,单击 No
  3. 现在选择服务提供者,Application Developer 将从其中生成一个客户机代理并选择 Generate => Client,如图 15 所示。
    图 15. 生成 JAX-WS 客户机代理
    生成 JAX-WS 客户机代理
    生成 JAX-WS 客户机代理
  4. 从 Web Service Client 向导中,确保选中 IBM WebSphere JAX-WS 作为 Web 服务运行时,然后单击 Client project:
  5. 指定 HelloWorldConsumer 作为 Client project name,然后选择 HelloWorldConsumer 作为客户机项目并单击 OK
  6. 接受默认值并单击 Finish。Application Developer 将生成 JAX-WS 客户机代理类和支持类。
  7. 右键单击生成的 HelloWorldConsumer 项目,并选择 New => Class
  8. 指定 com.ibm.dwexample 作为包名并指定 ClientTest 作为 Java 类名,然后单击 Finish
  9. 使用清单 2 中的代码替换生成的客户机代码并保存文件。
    清单 2. ClientTest.java
     package com.ibm.dwexample; import
                            com.ibm.dwexample.HelloWorldProvider; import
                            com.ibm.dwexample.HelloWorldProviderService;
                            public class
                            ClientTest { public static void main(String[] args) {
                            HelloWorldProviderService srv
                             = new HelloWorldProviderService();
                            HelloWorldProvider port
                             = srv.getHelloWorldProviderPort();
                             String
                            resp = port.sayHello("World");
                            System.out.println("[response] " +
                            resp); } }

现在,您已经创建了 JAX-WS 使用者,您需要将导入的策略集附加到使用者,然后生成客户端策略集绑定。为此,执行下面的步骤:

  1. 导航到 HelloWorldConsumer 项目并选择 Services => Clients => {http://dwexample.ibm.com/}HelloWorldProviderService => Manage Policy Set Attachment,如图 16 所示。
    图 16. 管理策略集附件
    管理策略集附件
    管理策略集附件
  2. 单击 Next,然后单击 Add
  3. 检查服务名是否被设置为 {http://dwexample.ibm.com/}HelloWorldProviderService,然后选择 Policy Set => MyUNT
  4. 输入 ClientUNTBinding 作为 Binding name,然后单击 OK,如图 17 所示。
    图 17. 将策略集附加到使用者
    将策略集附加到使用者
    将策略集附加到使用者

您现在已经将 Application Server 中创建的策略集附加到了 JAX-WS 使用者。您还为客户端绑定指定了名称(ClientUNTBinding)。最后的步骤是对绑定进行配置:

  1. 在绑定配置中选择 WSSecurity 策略类型并单击 Configure
  2. 选择 com.ibm.websphere.wssecurity.callbackhandler.UNTGUIPromptCallbackHandler 作为回调处理程序,如图 18 所示。
    图 18. JAX-WS 使用者绑定配置
    JAX-WS 使用者绑定配置
    JAX-WS 使用者绑定配置
  3. 单击 OK,然后单击 Finish

您现在已经指定了一个策略集以及与服务使用者对应的策略集绑定。您现在可以测试代码以确保它能够实际起作用。

运行样例应用程序

由于本文使用的代码演示的是使用 UsernameToken(即 SOAP 头部中的用户名和密码)作为身份验证令牌来实现 Application Server 的身份验证,因此您需要确保在执行测试前对 Application Server 启用了安全性。为此,从 Application Server 管理控制台中,确保选中 Enable administrative securityEnable application security。如果没有启用安全性,您将需要重启 Application Server 来使安全更改生效。

要测试应用程序,执行下面的步骤:

  1. 从 Application Developer 中,右键单击 ClientTest.java 并选择 Run As => Run Configurations
  2. 如图 19 所示,由于使用者需要使用 Java Authentication 和 Authorization Service (JAAS) 来传递 Username 凭证,为 VM arguments 指定下面的内容,以指向 JAAS 登录配置文件:
    -Djava.security.auth.login.config=
                            "C:\ProgramFiles\IBM\SDP\
                            runtimes\base_v7\profiles\was70profile1\
                            properties
                            \wsjaas_client.conf"
    图 19. 为 ClientTest 设置 JAAS 参数
    为 ClientTest 设置 JAAS 参数
    为 ClientTest 设置 JAAS 参数
  3. 单击 Run。您应当看到如图 20 所示的客户机结果以及如图 21 所示的服务器端结果。
    图 20. JAX-WS 使用者结果
    JAX-WS 使用者结果
    JAX-WS 使用者结果
    图 21. JAX-WS 提供者结果
    JAX-WS 提供者结果
    JAX-WS 提供者结果

结束语

除了身份验证、完整性和机密性以外,许多 Web 服务都需要实现授权。在本文中,您了解了如何配置 WebSphere Application Server V7 来选择一个安全令牌,它将作为 JEE 安全 principal 包含到 SOAP 头部。由于这种配置是在绑定级别对策略集完成的,每个 Web 服务端口可以具有不同的配置(如果需要的话),或者可以像本文一样,在服务级别指定配置。设置好配置后,开发人员就可以开始使用 JEE 授权 API,从而做出授权决策。对于基于 EJB 的 Web 服务,通过使用注释或部署描述符,经过配置的 JEE principal 就可以用于 JEE 的基于角色的授权检查。

致谢

作者衷心感谢 Bill Dodd 对本文的认真审阅。


下载资源


相关主题

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere, SOA and web services, Rational
ArticleID=476333
ArticleTitle=在 WebSphere Application Server V7 上通过 JAX-WS 实现消息级安全性: 集成 JEE 授权
publish-date=03222010