IBM WebSphere 开发者技术期刊: 通过 WebSphere Application Server V6 实现 Web 服务安全——第 2 部分

Username Token 和 SSL

在本 Web 服务安全系列文章的第 2 部分中,您将了解保护资源的一个最常用方法:使用用户名和密码。您将了解有关 UsernameToken Profile 的内容,以及如何通过 IBM® WebSphere® Application Server Version 6 将其用于 Web 服务。

Irina Singh (irinas@us.ibm.com), 高级顾问, IBM

Irina Singh 的照片Irina Singh 是美国的 IBM WebSphere 软件服务部资深顾问。Irina 具有十多年从事《财富》500 强公司的咨询工作的经验,她在大型机、WebSphere、Portal、J2EE、Web 服务和 SOA 方面表现出广泛的技术才能。她目前感兴趣的方面还包括 Web 服务安全。Irina 获得了位于印度坎普尔市的印度科技大学 (IIT) 的电子工程学士学位。



2006 年 8 月 03 日

摘自 IBM WebSphere 开发者技术期刊

引言

基于用户名和密码的安全在 Web 服务中非常普遍,Web 服务互操作性组织(Web services Interoperability Organization,WS-I)为其定义了一个标准,叫做 WS-Security UsernameToken Profile 1.0。为确保互操作性,WS-I 已细化了该标准。在本文中,您将了解有关 UsernameToken Profile 的内容,以及如何通过 WebSphere Application Server V6(以下称为 Application Server)将其用于保护 Web 服务。您将了解 Web 服务客户端如何使用 UsernameToken Profile 将 UsernameToken 传递到 Web 服务,还将了解与 UsernameToken 有关的常见风险以及如何降低这些风险。

标识、身份验证和授权

有些 Web 服务提供者要求服务请求者提供标识 其来源或其所有者的信息,然后才能访问相应的服务。这通常称为进行声明。WS-Security 已经标准化了可用于存储此信息的标头块(也称为令牌)。使用该请求的 Web 服务首先尝试验证 该令牌;即,查看请求者是否为系统中的有效用户。接着,Web 服务可能尝试查看与该请求关联的用户是否有权执行其尝试执行的操作。这叫做授权

UsernameToken 身份验证

有些 Web 服务提供者要求请求者通过用户名/密码组合来对自己进行身份验证。通过使用 Application Server V6 支持的 UsernameToken Profile 1.0,SOAP 消息请求可以符合标准的方式提供用户名和密码信息(或密码等效项、共享机密),以确保跨不同供应商套件的互操作性。UsernameToken 类似于 HTTP 基本身份验证,它提供的功能较少,但在各种场景中非常有效。

UsernameToken Profile 1.0 概述

正如前面提到的,令牌被放在 WS-Security 标头的 SOAP:envelope 标头元素中。UsernameToken 与 UsernameToken 元素相关联。您可以使用它提供用户名。可以通过包含一个 Password 元素来提供密码或共享机密。还可以指定密码的类型,即摘要形式 (PasswordDigest) 或明文形式 (PasswordText)。

下面的 SOAP 消息示例显示了一个包含 UsernameToken 的 SOAP 标头。请注意,为了清楚起见,已省去命名空间,仅保留了前缀。

<soapenv:Envelope>  
<soapenv:Header>
<wsse:Security >
<wsse:UsernameToken>
<wsse:Username>bob</ wsse:Username>
<wsse:Password Type="PasswordText">bob1</ wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body> ... </soapenvBody> 
</soapenv:Envelope>

UsernameToken Profile 互操作性

互操作性是开发 Web 服务时要考虑的重要事项。WS-I 重点解决了互操作性问题,并且针对互操作性目的限制了 UsernameToken Profile 1.0 OASIS 标准。大多数 Java™ 2 Extended Edition (J2EE) 和 Microsoft™ .NET™ 服务器都可以很好地互操作,并且可以方便地使用彼此的 Username Token。

通过 Application Server V6 保护 Username Token

Application Server V6 支持 Username Token Profile 1.0,但必须以明文形式指定密码。UsernameToken 规范允许使用单向安全哈希来保护摘要 形式的密码,但 Application Server V6 中没有提供该功能。简单的哈希(例如有时在 HTTP 基本身份验证中使用的哈希)易受到回复攻击的威胁,因为攻击者可以很容易地探查到通信并能够在不知道密码的情况下回复哈希。UsernameToken 规范意识到这一点并指定密码摘要(如果使用)必须在 Password Digest 中包含 nonce(一个随机号)和创建时间戳,以便将摘要绑定到 nonce 和时间戳。将 nonce 与时间戳检查一起使用时,可以有效地阻止回复攻击。Application Server 负责确保不会多次发送同一个 nonce。

UsernameToken 规范建议了下列应对措施来处理此威胁:

  • Web 服务生产者应拒绝任何没有同时使用 nonce 和创建时间戳的 UsernameToken。
  • Web 服务生产者应提供一个时间戳有效性限制,任何具有失效时间戳的 UsernameToken 都应被拒绝。作为一个指导原则,您可以使用一个五分钟的值作为检测回复的最短期限,超过此限制将拒绝回复。
  • 用过的 nonce 应被缓存一个期限,该期限至少应与时间戳有效性限制周期一样长,并且应拒绝具有用过的 nonce(已经在缓存中)的 UsernameToken。

恶意攻击者仍可以探查连接(请注意,缺省情况下密码摘要没有被加密)并回复整个 UsernameToken,因此 nonce 和时间戳检查是缺一不可的。可以使用 SSL 对数据进一步进行加密,但这只在点到点场景中较为有效,在具有中介层的场景中效果不太好。对于更为端到端的方法,则应使用 WS-Security 中的 XML Encryption 加密 UsernameToken,我们将在本系列的后续文章中介绍。

如果没有上述保障措施,UsernameToken 根本无法完全达到其目的。

何时使用 UsernameToken

应在下列场景中使用 UsernameToken:

  • 当某个服务要求基于用户名和密码或者共享机密/密码等效项进行消息级安全身份验证时。
  • 当互操作性至关重要时。UsernameToken Profile 是在异类环境中运行的应用程序之间传递身份验证信息的好方法。
  • 对于特别复杂的 X.509 证书,不值得使用 XML 加密 (XML Encryption) 和 XML 数字签名 (XML Digital Signature),因为安全性不是首要考虑事项。(请记住,您需要加密 UsernameToken 以便它能够得到正确保护)。UsernameToken 易于使用、配置和维护。

示例场景

在本文中,您将通过下列示例场景了解如何配置和保护 UsernameToken。

  1. Web 服务是一个简单的温度转换程序,并运行在 Application Server V6 上。该 Web 服务 (ConverterEAR.ear) 是使用以下两个方法的无状态会话 bean:
    getCelsius,用于将华氏温度转换为摄氏温度:
    public float getCelsius(float Fahrenheit ) throws Exception { }
    getFahrenheit,用于将摄氏温度转换为华氏温度:
    public float getFahrenheit(float Celsius) throws Exception { }
  2. 该 Web 服务部署在 Application Server V6 中。您将配置 Web 服务以接受 SOAP 标头并验证传递到 UsernameToken 中的身份。身份验证由使用 IBM Directory Server 作为用户注册中心的 Application Server 完成,并要求 SOAP 请求者消息在 SOAP 标头中包含用户名和密码。温度转换程序服务使用 J2EE 授权来确保用户有适当的权限来执行该服务中的方法。它包含的 J2EE 角色称为 Agents,该角色映射到名为 Managers 的LDAP 组。要执行这些方法,用户必须是 LDAP 中 Managers 组的成员。
  3. Web 服务客户端是一个 servlet,并运行于 Application Server V6。客户端将用户名和密码传递到 UsernameToken。您可以配置客户端扩展以生成 UsernameToken 标头,并将它们插入 SOAP 消息请求。
  4. SOAP 请求通过 SSL 发送到 Application Server,因此可以保护 UsernameToken。

先决条件

示例场景已使用 Application Server V6 和 IBM Directory Server V6 进行测试。要运行示例,需要确保满足以下条件:

  1. 安装了 IBM Directory Server 并配置了前缀 o=ibm,c=us。下列用户必须存在:
    • cn=bob,o=ibm,c=us
    • cn=wasadmin,o=ibm,c=us
    • cn=ldapbind,o=ibm,c=us
    您可以使用实现 LDAP V3 协议的任何 LDAP。这可以确保为示例场景正确设置注册中心。
  2. 通过轻量级第三方身份验证 (LTPA) 并使用 LDAP 启用了 Application Server 全局安全,使用的参数如下:
    • 主动身份验证机制 = LTPA
    • 主动用户注册中心 = 轻量级目录访问协议 (LDAP) 用户注册中心
    • 服务器用户 Id = cn=wasadmin,o=ibm,c=us
    • 基本专有名称 = o=ibm,c=us
    • 绑定专有名称 =cn=ldapbind,o=ibm,c=us
    • 高级 LDAP 设置 = 用户过滤器: (&(cn=%v)(objectclass=organizationalPerson))
    • 组过滤器 = (&(cn=%v)(objectclass=groupOfUniqueNames))
    • 用户 Id 映射 = *:cn
    • 组 Id 映射 = *:cn
    将其他参数保留为缺省值。
  3. Application Server 使用 Bind id cn=ldapbind,o=ibm,c=us 绑定到 LDAP。因此,确保了用户 cn=ldapbind,o=ibm,c=us 有权读取和搜索具有 o=ibm,c=us 后缀的 LDAP 目录树。
  4. 需要使用 Rational® Application Developer V6 运行这些示例。确保:
    • 已安装和更新了 Rational Application Developer。
    • 在 Rational Application Developer 测试环境中创建了 Application Server V6 测试服务器
    • 已将测试服务器更新到 Application Server V6.0.2.5
  5. 下载本文包括的 zip 文件,并将其解压缩到 C: 驱动器。这将创建名为 C:\UsernameTokenArticle 的目录,并将下面的文件放在此目录中:
    • ConverterEAR.ear
    • ConvertClientEAR.ear
    • importldif.ldif。

步骤总结

Web 服务提供者称为 ConverterEAR.ear,客户端称为 ConvertClientEAR.ear。您将完成本文中的下列步骤:

  1. 导入和检查示例 Web 服务应用程序
  2. 导入和检查 Web 服务客户端应用程序
  3. 为 Username Token 配置 Web 服务客户端安全扩展和绑定
  4. 为验证 Username Token 配置 Web 服务安全扩展和绑定
  5. 使用 TCP/IP 监视器测试 Web 服务
    • 以明文形式查看 SOAP 消息
    • 使用 SSL 并通过 TCP 监视器查看。

步骤 1:导入和检查示例 Web 服务企业应用程序

导入本文包括的示例 Web 服务应用程序。该应用程序包括:

  • 一个名为 ConverterEAR.ear 的 Web 服务。
  • 一个名为 ConvertClientEAR.ear 的 Web 服务客户端。
  • 一个将用于构建 LDAP 用户和组的 importldif.ldif 文件。

启用 Web 服务部署功能

您需要在 Rational Application Developer 工作区中启用 Web 服务部署功能。要完成此任务,请执行以下步骤:

  1. 单击 Window => Preferences => Workbench => Capabilities
  2. 确保启用了 Advanced J2EEWeb service DeveloperWeb Developer (advanced) 的所有功能。您可能需要展开每个选项,以确保启用了所有这些功能,如图 1 中所示:
    图 1. Rational Application Developer 中的 Workbench 功能
    图 1. Rational Application Developer 中的 Workbench 功能

导入企业应用程序

要导入 ConverterEAR.ear 文件,请执行下列操作:

  1. 启动 Rational Application Developer,并转到 J2EE 透视图。如果 J2EE 不是所列的选项之一,则请选择 >Other => J2EE
  2. 选择 File => Import 以启动文件导入向导。
  3. 选择 EAR File,然后单击 Next
  4. 输入 EAR 文件名。如果将下载材料解压缩到 C:驱动器,则名称为:C:\UsernameTokenArticle\ConverterEAR.ear。
  5. 接受项目名的缺省值,并确保为 Target Server 选择了 WebSphere Application Server V6
  6. 单击 Finish。(如果收到有关未使用导入的警告,可以忽略它们。还可以在 Workspace PreferencesJava Compiler 部分禁用此警告。)

导入和检查企业应用程序

在这一部分,我们将导入和查看企业应用程序。

  1. ConvertEAR 是一个企业项目,包含一个名为 ConverterEJB.jar 的 EJB 模块和一个名为 ConverterRouterWeb.war 的 Web 模块。从 J2EE 透视图选择 EJB Projects => ConverterEJB => Session Beans
  2. 存在一个无状态会话 Bean TemperatureConverter。打开 TemperatureConverterBean.java 类,并注意该类包含下面两个公开为 Web 服务的方法:
    	public float getCelsius(float Fahrenheit ) throws Exception {  }
    	public float getFahrenheit(float Celsius) throws Exception  {  }

    这些方法可以由 Web 服务客户端调用。
    图 2. Converter EJB 项目文件
    图 2. Converter EJB 项目文件
  3. 现在选择 ConverterEJB => Deployment Descriptor: ConverterEJB 来查看 EJB 部署描述符。
  4. 单击 Assembly 选项卡。您将看到名为 Agents 的 J2EE 安全角色。您可以看到我们已经将 EJB 的方法映射到 Agents 安全角色,如图 3 所示。
    图 3. EJB 部署描述符中的 Agents J2EE 角色
    图 3. EJB 部署描述符中的 Agents J2EE 角色
  5. 关闭 EJB 部署描述符。
  6. 接下来,我们需要确保将 Agents 角色映射到应用程序部署描述符中 LDAP 注册中心内的实际用户和组。为此,请完成以下操作步骤:
    1. 选择 Enterprise Applications => ConverterEAR
    2. 双击 Deployment Descriptor:ConverterEAR 打开应用程序部署描述符。
    3. 单击 Security 选项卡,并选择 Agents。您可以看到 Agents 角色被映射到一个 LDAP 组 cn=managers,ou=users,o=ibm,c=us
      图 4. 将 J2EE 角色映射到 Groups 的应用程序部署描述符
      图 4. 将 J2EE 角色映射到 Groups 的应用程序部署描述符
    4. 关闭应用程序部署描述符
  7. 现在,通过选择 EJB Projects => ConverterEJB => ejbModule => META-INF-wsdl => TemperatureConverter.wsdl,查看 Web 服务的 WSDL 文件。
  8. 打开文件,并单击 Source 选项卡。wsdl 文件定义与 TemperatureConverter 无状态会话 Bean 的两个方法相对应的两个 SOAP 操作。注意,此 wsdl 还将 Web 服务的位置定义为 https://localhost:9443/ConverterRouterWeb/services/TemperatureConverter。
  9. 关闭 WSDL 文件。
  10. 接下来,查看一下 Web 服务部署描述符,即 ejbModule 的 META-INF 目录中的 webservices.xml,如图 5 所示。双击以打开该文件,并单击 Port Components
  11. 选择 TemperatureConverter,并检查其属性。注意,EJB Link 选项指示实现的 Bean 是一个无状态会话 Bean。
    图 5. webservices.xml 中的 Port Components
    图 5. webservices.xml 中的 Port Components
  12. 关闭 webservices.xml。
  13. 最后,通过选择 Dynamic Web Projects => ConverterRouterWeb 查看一下 Router Web 项目,并展开它。此 Web 项目用于从客户端接受 SOAP 请求,并将该请求转发到 ConverterEJB 项目中的 TemperatureConverter 会话 Bean。在本示例中,需要此路由器项目,因为客户端会通过 HTTP 发送 SOAP 消息,并且不能直接通过 HTTP 调用 EJB。因此,Web 项目会从客户端接受请求,并将它们转发到 ConverterEJB。注意,此项目包含一个定义为 TemperatureConverter 的 Servlet,它具有一个映射到 services/TemperatureConverter 的 URL。可以通过 URL ConverterRouterWeb/services/TemperatureConverter 访问此 Servlet。
  14. 关闭任何打开的文件。

步骤 2:导入并检查 Web 服务客户端应用程序

在这一部分中,我们将导入并查看 Web 服务客户端应用程序。

JSR 109 Web 服务客户端

JSR 109 定义用于访问 Web 服务的托管客户端模式。此客户端必须在容器中运行,并使用 JNDI 查找功能来查找服务实例。客户端容器会绑定由 java:comp/env 客户端环境命名上下文中的该引用所描述的服务接口。因此,您需要在客户端的部署描述符中声明一个本地服务引用。以下代码段显示如何使用 JNDI 查找获得指向基于 J2EE 的 Web 服务的引用:

InitialContext ctx = new InitialContext();
MyWebService myService =
(MyWebService)ctx.lookup("java:comp/env/services/MyWebService");

导入 Web 服务客户端应用程序

按照与导入企业应用程序中相同的步骤,导入 Web 服务客户端 C:\UsernameTokenArticle\ConvertClientEAR.ear。现在,查看一下 Web 服务客户端:

Web 服务客户端是一个从 TemperatureConverter.wsdl 生成的 Web 客户端。其中有两个不是由 Rational Application Developer 创建的重要文件:ConverterManagedClientForm.jsp 和 ManagedClientServlet.java。

  1. 选择 Dynamic Web Projects => ConvertClientWeb => Java Resources => JavaSource => com.converter.servlets => ManagedClientServlet.java
  2. 打开此文件,并检查 doPost 方法。注意,这是一个托管客户端,我们将对该服务使用本地 JNDI 查找。
    InitialContext ctx = new InitialContext();
    TemperatureConverterService locator = (TemperatureConverterService) 
    ctx.lookup("java:comp/env/service/TemperatureConverterService");
    TemperatureConverter converterStub = locator.getTemperatureConverter();
  3. 关闭文件。
  4. 选择 Open Dynamic Web Projects => ConvertClientWeb => WebContent => WEB-INF => web.xml 并单击 References
  5. 选择 ServiceRef service/TemperatureConverterService 并检查右边的详细信息。您将会看到 Service 文件、WSDL 和 JAX-RPC 映射文件。
    图 6. 指向服务的客户端 Web 部署描述符引用
    图 6. 指向服务的客户端 Web 部署描述符引用
  6. 为 Web 服务 Web 客户端配置 web.xml Port Qualified Name Binding Details
    1. 选择 Dynamic Web Projects => ConvertClientWeb => WEB-INF => web.xml => WS-Binding
    2. 单击 web.xml 的 WS-Binding 选项卡。
    3. 展开 Port Qualified Name Binding Details
    4. HTTP SSL Configuration Name 字段中,输入 <Your Node Name>/DefaultSSLSettings,其中 <Your Node Name> 是 Application Server 测试环境的节点。要找到节点名,请登录 Application Server 管理控制台,单击 application servers,选择 server1,然后查看运行时配置,如图 7 所示,用自已的节点名替换 irinat402Node01。

      注意,要调用其他组织提供的服务,您可能需要为其他组织配置特定的 SSL 配置。有关如何配置 SSL 以便用于 Web 服务的讨论,请参阅本系列文章的第 1 部分:“通过 WebSphere Application Server V6 实现 Web 服务安全”


      图 7. 编辑 web.xml
      图 7. 编辑 web.xml
  7. 关闭任何打开的文件。

步骤 3:为 UsernameToken 配置 Web 服务客户端安全扩展和绑定

启用 Web 服务安全后,客户端 SOAP 安全处理程序会生成 SOAP 标头,并将它们插入到 SOAP 消息请求中。 服务器端 SOAP 安全处理程序为 UsernameToken 解析 SOAP 请求消息,然后使用令牌中的用户 ID 和密码验证用户是否与应用服务器上的注册相符。

为了添加 Web 服务安全,您需要在服务器上编辑 Web 服务部署描述符文件 webservices.xml,在客户端上编辑 Web 部署描述符文件 web.xml。可以使用 Rational Application Developer 图形编辑器执行此操作。

首先,为 Web 服务客户端配置 WS-security:

  1. 在 J2EE 透视图中,通过选择 Dynamic Web projects => ConvertClientWeb 打开 ConvertClientWeb 部署描述符。
  2. 双击 Deployment Descriptor: ConvertClientWeb。Web 部署描述符包含用于配置 WS-security 的 WS-Extension 和 WS-Binding。
  3. 单击 WS-Extension,并展开 Request Generator Configuration。在 Port QName Bindings 中选择 TemperatureConverter,如图 8 所示:
    图 8. Web 服务客户端的 web.xml 中的 WS-Extension 选项卡
    图 8. Web 服务客户端的 web.xml 中的 WS-Extension 选项卡
  4. 展开 Security Token,并单击 Add
  5. 在 Security Token 对话框中,在 Name 字段中输入 Client_username_token
  6. Token type 字段中,选择 Username
  7. URI 字段保持空白,如图 9 所示。
    图 9. 添加令牌
    图 9. 添加令牌
  8. 单击 OK 创建安全令牌。
  9. 现在,您需要添加一个回调处理程序,以便将安全标头 Username Token 类型添加到 SOAP 请求中。
  10. 单击 WS-Binding。展开 Security Request Generator Binding Configuration
  11. 选择服务引用 Service/TemperatureConverterService
  12. 展开 Token Generator,并单击 Add,如图 10 所示:
    图 10. web.xml WS-Bindings 选项卡
    图 10. web.xml WS-Bindings 选项卡
  13. 在 Token Generator 对话框中,输入以下内容,如图 11 所示:
    • Token generator nameclient_username_token_gen
    • Token generator class:选择 UsernameTokenGenerator
    • Security token:选择 client_username_token,以指示正在将生成器类与 WS-Extension 中定义的令牌关联。
    • 选中 Use Value Type,以指示您在此处输入的任何值将在令牌中使用。
    • Value Type:选择 Username Token
    • Local name:此字段会自动填充。
    • Call back handler:选择 NonPromptCallBackHandler。此处理程序不对客户端进行提示,它返回在此对话框中指定的用户名和密码。
    • User ID:输入 bob 或与 LDAP 组管理员关联的任何其他用户 ID。这非常重要,因为 Web 服务会被映射到 Agents 安全角色,后者会被映射到 LDAP 组 cn=managers,ou=groups,o=ibm,c=us
    • Password:输入 bob 的密码。

    图 11. 用于 Web 服务客户端的 web.xml 上的 WS-Binding 选项卡
    图 11. 用于 Web 服务客户端的 web.xml 上的 WS-Binding 选项卡
  14. 单击 OK,然后保存并关闭 web.xml。

下表简要总结了该配置:

表 1. web.xml 中 Web 服务客户端配置
web.xml 上的 WS-Extension 选项卡web.xml 上的 WS-Binding 选项卡
添加 Security Token(称为 client_username_token)添加 Token Generator(callbackhandler 类,以及相应的令牌类型和值)
存放编辑内容的文件:WEB-INF/ibm-webservicesclient-ext.xmi存放编辑内容的文件:WEB-INF/ibm-webservicesclient-bnd.xmi

现在,您已经完成了客户端配置。

步骤 4:为验证 UsernameToken 配置 Web 服务安全扩展和绑定

在此步骤中将配置 Web 服务,以正确处理由 Web 服务客户端在 SOAP 请求中发送的安全令牌。Web 服务部署描述符包含用于指定 Web 服务安全的 Extensions 和 Binding Configurations 页。

  1. 从 Project Explorer 视图中,展开 EJB Projects => ConverterEJB => ejbModule => META-INF
  2. 双击 webservices.xml,打开 Web 服务部署描述符。
  3. 单击 Extensions 选项卡。它位于 Port Component Binding => Select TemperatureConverter 中。
  4. 展开 Request Consumer Service Configuration Details
  5. 展开 Required Security Token,并单击 Add。(请注意:如果 Add 按钮变灰,请选择左边的 Port Component Binding => Select TemperatureConverter
  6. 在 Required Security Token 对话框中,指定以下内容,如图 12 所示:
    • Name:输入 reqcon_username_token
    • Token type:选择 Username
    • Local name 已经填充。
    • Usage type:选择 Required,使该请求必须包含该令牌。
      图 12. webservices.xml 的 Extensions 选项卡上的 Required Security Token 对话框
      图 12. webservices.xml 的 Extensions 选项卡上的 Required Security Token 对话框
    • 单击 OK
  7. 展开 Caller Part,并单击 Add
  8. 在 Caller Part 对话框中,指定以下内容,如图 13 所示:
    • Name:输入 basicAuth
    • Token type:选择 Username
    • Local name 已经填充。

    图 13. webservices.xml 的 Extensions 选项卡上的 Caller Part 对话框
    图 13. webservices.xml 的 Extensions 选项卡上的 Caller Part 对话框
  9. 单击 OK。Caller Part 用于将 UsernameToken 标识为令牌标识。Caller Part 向 Application Server 指示它可以使用令牌标识在其自己的注册中心中进行身份验证。
  10. 单击 Binding Configurations 选项卡。
  11. 展开 Request Consumer Binding Configuration Details。展开 Token Consumer,并单击 Add
  12. 输入以下信息,如图 14 所示。
    • Token consumer class:选择 UsernameTokenConsumer
    • Security token:选择 reqcon_username_token
    • 选中 Use value type
    • Value Type:选择 UsernameToken
    • 选中 Use jaas.config
    • Jaas.config name:输入 system.wssecurity.UsernameToken

    图 14. webservices.xml 上的绑定配置选项卡
    图 14. webservices.xml 上的绑定配置选项卡
  13. 单击 OK,并保存 webservices.xml。

下表简要总结了您为 Web 服务部署描述符完成的配置:

表 2. webseervices.xml 中的 Web 服务配置
webservices.xml 上的扩展选项卡webservices.xml 上的绑定配置选项卡
添加类型 Username 的 Required Security Token,并将 Usage 设置为 Required(在本示例中称为 reqcon_username_token)添加 Token consumer class(即 UsernameTokenConsumer 类,它与在 Extensions 选项卡中创建的安全令牌关联,将 Token Type 设置为 Username,将 jaas.config 名称设置为 system.wssecurity.UsernameToken)
添加 Caller Part,将 Token Type 设置为 Username Token(在本示例中称为 basicAuth)。
存放编辑内容的文件:ejbModule/META-INF/ibm-webservices-ext.xmi存放编辑内容的文件:ejbModule/META-INF/ibm-webservices-bnd.xmi

步骤 5:使用 TCP/IP 监视器测试 Web 服务

现在已准备好使用 TCP 监视器测试 Web 服务。要执行此操作,请将 ConverterEAR 和 ConvertClientEAR 添加到 Application Server V6。确保在 Application Server 测试环境中启用了全局安全。完成以下步骤:

  1. 双击 Rational Application Developer 中的 Application Server V6 测试服务器。
  2. 在服务器设置中,确保为服务器连接类型启用了 SOAP(而不是 RMI),如图 15 所示。
    图 15. 使用 SOAP 连接器端口
    图 15. 使用 SOAP 连接器端口
  3. 展开 Security,确保服务器用户 ID 和密码与您在 Application Server 管理控制台上输入的相同。Application Server 测试环境将使用这些安全设置。
    图 16. 安全设置
    图 16. 安全设置
  4. 选择 Dynamic Web Projects => ConvertClientWeb =>Web Content => ConverterManagedClientForm.jsp
  5. 右键单击并选择 Run on Server。选中该选项,使 Application Server V6 测试服务器成为缺省服务器。输入一个值,并单击 Submit
  6. 导航到 RAD_Install_ROOT\runtimes\base_v6\profiles\default\logs\server1\SystemOut.log。

    找到以下输出行:

     EJB******************: Principal - bob


    这指示 Application Server 能够对 SOAP 标头中接收到的 userid 进行身份验证,并对属于 Agents 角色的 Bob 进行授权;也就是说,Bob 是 LDAP 管理员组的成员。如果 Web 服务正确执行,则应看到一个返回结果。

使用 TCP 监视器查看 SOAP 标头

您可以使用 TCP 监视器拦截和检查进出 Web 服务的 SOAP 通信。此监视器是承载 Web 服务的服务器代理。您需要为该工具完成以下两个步骤:配置 TCP/IP 监视器和重定向客户端,以便将消息发送到监视器,而不是 Web 服务。

  1. 选择 Navigate to Window => Preferences => Internet => TCP/IP Monitor。单击 Add 创建一个新的 TCP 监视器。输入如图 17 所示的信息:
    图 17. TCP 监视器
    图 17. TCP 监视器
  2. 单击 OK
  3. 单击 Start 以启动 TCP 监视器。监视器在端口 9081 创建,并将通信转发到端口 9080。
  4. 单击 OK,关闭参数窗口。TCP 监视器仅在获得通信时显示。
  5. 配置 Web 服务客户端,以便将 Web 服务请求发送到端口 9081,而不是端口 9080 或 9443(因为您已启用了安全功能)。为此,您需要在存根上设置端点地址属性,以便在 http://localhost:9081/ ConverterRouterWeb/services/TemperatureConverter 调用 Web 服务。TCP/IP 监视器接收 Web 服务请求,并将消息路由到端口 9080 上的同一端点。
  6. 选择 Dynamic Web Projects => ConvertClientWeb => Java Resources => JavaSource => com.converter.servlets => ManagedClientServlet.java。打开此文件,并检查 doPost 方法。注释掉以下行:
    ((javax.xml.rpc.Stub)converterStub)._setProperty(
    "javax.xml.rpc.service.endpoint.address",
    "http://localhost:9081/ConverterRouterWeb/services/TemperatureConverter");
  7. 保存并关闭 ManagedClientServlet.java。
  8. 选择 Dynamic Web Projects => ConvertClientWeb => WebContent => ConverterManagedClientForm.jsp
  9. 右键单击 ConverterManagedClientForm.jsp,并选择 Run => Run on Server。或者,在浏览器中输入以下 URL:https://localhost:9443/ConvertClientWeb/ConverterManagedClientForm.jsp
  10. 输入一个表示温度的值,如 100。
  11. 返回到 TCP 监视器,并将其扩展。选择 XML 视图以设置 XML 消息的格式。注意,此消息现在包含一个带有 Securitysoapenv 元素,该元素包含 UsernameToken。但是,用户名和密码都是明文形式的。
    <soapenv:Header>
    <Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/
                            oasis-200401-wss-wssecurity-secext-1.0.xsd" 
         soapenv:mustUnderstand="1">
    <UsernameToken>
    <Username>bob</Username>
    <Password Type="http://docs.oasis-open.org/wss/2004/01/
                      oasis-200401-wss-username-token-profile-1.0
         #PasswordText"> bob1</Password>
    </UsernameToken>
    </Security>
    </soapenv:Header>

使用 SSL 进行通信,并在 TCP 监视器上查看消息

以明文形式发送消息是不可接受的解决方案。这样消息并不安全,因为外部查看者可以取读其中的用户名和密码。为了解决此问题,我们将使用 SSL 执行从客户端到服务器的通信。

由于客户端运行在已启用全局安全的 Application Server V6 上,所以 Application Server 将使用缺省存储文件侦听 SSL 端口。Application Server Web 容器将 9443 用于 SSL 请求。(请注意:您可以登录管理控制台,并导航到 Servers => Application Servers => server1 or your application server =>,以便查找 Web 容器的 SSL 端口。展开 Web Container Settings => Web Container Transport Chains。分配给 WCInboundDefaultSecure 的端口号是应用程序服务器缺省主机的 SSL 端口。缺省情况下,WCInboundDefaultSecure 使用 9443。

您需要配置 TCP 监视器,以便将请求转发到 9443 端口(即,用于 Application Server Web 容器的 SSL 端口):

  1. 选择 Windows => Preferences => Internet => TCP/IP Monitor,并单击 Add
  2. Local monitoring port 字段中,输入 1234
  3. 在 Monitor Port 字段中,输入 9443
  4. 在 Monitor Type 字段中,选择 TCP/IP,如图 18 所示。
    图 18. 用于监视 SSL 的 TCP 监视器选择类型 TCP/IP。
    图 18. 用于监视 SSL 的 TCP 监视器选择类型 TCP/IP。
    这意味着 TCP 监视器在 1234 接收请求,并将它们转发到 9443。
  5. 启动 TCP 监视器。
  6. 打开 Dynamic Web Projects => ConvertClientWeb => Java Resources => JavaSource => com.converter.servlets => ManagedClientServlet.java
  7. doPost 方法中,注释掉以下行:
    ((javax.xml.rpc.Stub)converterStub)._setProperty(
    "javax.xml.rpc.service.endpoint.address",
    "https://localhost:1234/ConverterRouterWeb/services/TemperatureConverter");

    确保已注释以下行:
    // "http://localhost:9081/ConverterRouterWeb/services/TemperatureConverter");
  8. 保存并关闭 ManagedClientServlet.java。
  9. 导航到 Dynamic Web Projects => ConvertClientWeb => WebContent => ConverterManagedClientForm.jsp
  10. 右键单击 ConverterManagedClientForm.jsp,并选择 Run => Run on Server。或者,在浏览器中输入以下 URL:https://localhost:9443/ConvertClientWeb/ConverterManagedClientForm.jsp。
  11. 输入 212 作为温度值,并查看 TCP 监视器。监视器不显示任何文本。

使用带有动态用户 ID 和密码的 UsernameToken

返回到步骤 3,在该步骤中您使用包含用户 ID bob 和密码的 UsernameToken 配置了 Web 服务客户端(如步骤 3 中的 4 个图所示)。在本文中,您将用户名和密码添加到了客户端的部署描述符。但是,有时您需要根据某些标准动态检索客户端的身份验证数据(如用户 ID 和密码)。例如,您可能没有密码,并需要从用户存储库检索它。在这些情况下,您需要编写一个自定义 CallbackHandler。

Application Server 提供一个框架,用于在消息的发送方一侧生成安全令牌,并在消息的接收方一侧验证这些安全令牌。该框架基于 Java 身份验证和授权服务 (JAAS) 应用程序编程接口 (API)。如果要生成具有动态身份验证数据的 UsernameToken,则需要编写一个自定义 callbackHandler 实现。下面是一些一般原则:

  • 对于您自已的 CallbackHandler 实现,必须提供 javax.security.auth.callback.CallbackHandler 接口;例如 myCallbackHandler()。该类与以下代码类似:
    myCallbackHandler implements javax.security.auth.callback.CallbackHandler 
    { 
    }
  • 在此类中,您可以处理 javax.security.auth.callback.NameCallback 或 javax.security.auth.callback.PasswordCallback 实现。如果其中任意一个填充了数据,就会创建一个 wsse:UsernameToken 元素。
  • 实现 com.ibm.wsspi.wssecurity.auth.callback.CallbackHandlerFactory 接口,该接口是一个用于实例化 javax.security.auth.callback.CallbackHandler 实现的工厂。
  • Web 服务安全运行时会调用工厂 (com.ibm.wsspi.wssecurity.auth.callback.CallbackHandlerFactory) 中的 myCallbackHandler(),以获取 javax.security.auth.CallbackHandler 对象的实例。将该对象传递到 JAAS 登录配置。

在此系列文章的后续文章中,我们将详细探讨如何实现 CallbackHandler。

结束语

消息级的安全是面向服务体系结构 (Service Oriented Architecture) 中的重要组件。在本文中,我们介绍了使用 Web 服务中 UsernameToken 安全的方式和时间、一些与使用相关的风险和一些用于最大程度地降低风险的建议。在此示例中,我们使用了传输级别的安全,因为密码是明文形式的。我们了解了 Rational Application Developer 的图形工具是如何使配置 Web 服务的安全变得更加容易,并了解到如何使用 Token Generator 类生成一个令牌,以及如何使用 Token Consumer 类对令牌进行验证。我们还介绍了保护 UsernameToken 的技巧。有时,在跃点之间可能有一些中间层,在这种情况下,您不能依赖于 SSL。在此类场景中,您需要应用消息级安全对消息或消息的某些部分进行加密。在本系列文章中的下一部分中,我们将对此进行介绍。后续文章将讨论 XML 加密、XML 数字签名以及与其他补充技术的集成(全部在 Web 服务上下文中)。

致谢

作者在此感谢 Tony Cowan 和 Aditya Narayan,他们做了许多宝贵的批注和审阅。

本系列的其他文章


下载

描述名字大小
project filesUsernameTokenArticle.zip  ( HTTP | FTP )89KB

参考资料

学习

获得产品和技术

  • 使用 IBM 试用软件开发您的下一个项目,可直接从 developerWorks 下载这些试用软件。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere, SOA and web services
ArticleID=151788
ArticleTitle=IBM WebSphere 开发者技术期刊: 通过 WebSphere Application Server V6 实现 Web 服务安全——第 2 部分
publish-date=08032006