跨 WebSphere Application Server 安全域的 SAML 断言

Security Assertion Markup Language (SAML) 正在成为跨企业边界创建单点登录 (SSO) 解决方案的常用技术。本文讨论如何使用 IBM® WebSphere® Application Server V7.0 Fix Pack 7 中的 SAML 支持跨不同安全域中的企业边界断言 SAML 令牌,以及使用外部安全域用户身份和定制的 SAML 组属性直接做出访问控制决策,这一切都基于信任关系。通过三个点上的策略集绑定配置执行信任关系检验,从而确保真实性和防御安全威胁。本文说明这种技术与身份映射方式相比更容易管理、可伸缩性更好。 本文来自于 IBM WebSphere Developer Technical Journal 中文版

Chunlong Liang, WebSphere Web 服务开发人员, IBM

Chunlong Liang 是一位从事 WebSphere 平台上 Web 服务安全性的开发人员。Chunlong 从事 WebSphere 开发已经超过 9 年,为 WebSphere 平台开发了许多安全特性。在加入 WebSphere 团队之前,Chunlong 做了 6 年保险精算师和程序员,做了 3 年统计员。



Ching-Yun (C.Y.) Chao, Ph.D., 资深软件工程师, IBM

Ching-Yun (C.Y.) Chao 是一位 WebSphere Web 服务安全性架构师。C.Y. 从事 WebSphere Application Server 开发已经超过 10 年。C.Y. 设计和开发了许多 WebSphere 安全特性。在从事 WebSphere 开发之前,C.Y. 是 IBM PC 服务器高可用性系统集群项目的主要架构师和开发人员。C.Y. 于 2006 年荣获 IBM Master Inventor 并拥有安全性和高可用性系统集群方面的许多专利。C.Y. 从 Northwestern University 取得了电子工程博士学位。



2010 年 7 月 22 日

简介

Security Assertion Markup Language (SAML) 是用于表示和交换用户身份、身份验证和属性信息的 OASIS 开放标准。SAML 正在成为创建单点登录 (SSO) 解决方案的常用技术。对于希望向其业务伙伴的已授权用户提供业务服务的公司,可以应用这种技术创建 SSO 解决方案,从而跨企业联合 Web 服务资源。

请考虑一个业务场景:您希望自己的用户能够访问伙伴公司的业务服务。最好的 SSO 效果是,用户只需向您的企业验证身份,而不需要向其他公司验证身份。当用户访问 Web 服务资源时,可以使用 SAML 令牌传递用户身份和属性数据。由于业务和私密性问题,这些公司很可能不会把它们的多个用户目录整合为单一公用用户目录。这意味着 SAML 令牌将包含来自外部安全域的用户身份,它们不是在业务服务提供者的用户目录中定义的。本文讨论如何使用 IBM® WebSphere® Application Server V7.0 Fix Pack 7 中的 SAML 支持跨多个安全域边界断言 SAML 令牌,以及使用外部安全域用户身份和定制的 SAML 组属性直接做出访问控制决策。您会看到,与身份和组映射技术相比,根据信任关系断言外部身份和定制的组属性更容易管理。


SAML 令牌

SAML 令牌由令牌颁发者进行数字签名以确保令牌的完整性。业务服务提供者可以检验令牌颁发者的数字签名,从而确认 SAML 令牌中用户身份的真实性。检验令牌颁发者的数字签名是检验业务伙伴之间的信任关系的基础。本文描述用于断言 SAML 令牌以在应用服务器运行时环境中创建用户安全上下文的信任模型。本文还包含一个 EJB™ 3.0 Java™ API for XML Web Services (JAX-WS) 示例应用程序,通过它说明如何根据 SAML 令牌颁发者和 Web 服务提供者之间的信任关系配置跨安全域 SAML 断言。您将通过这个应用程序学习如何配置业务服务,从而使用 SAML 令牌做出资源访问控制决策。

使用应用服务器 SAML 令牌断言信任模型构建 SSO 解决方案有许多优点:

  • 对于用户来说,优点是他们只需向自己的安全域验证身份,然后就能够通过信任关系访问业务伙伴的 Web 服务资源。用户不需要管理其他安全域的账号和身份验证数据。
  • 对于 IT 管理员来说,明显的优点是通过使用基于标准的 SAML 技术实现广泛的第三方互操作性。
  • 对于 IT 管理员的另一个主要优点是,降低联合业务资源时的身份管理成本。不需要整合公司的用户目录,即使这在业务场景中是可行的,这个任务也很麻烦。
  • 对于 IT 管理员的另一个优点是,保留外部安全域中的用户身份,可以在安全和业务审计记录中包含它们。

除非另外说明,本文中的 WebSphere Application Server 是指应用了 Fix Pack 7 (V7.0.0.7) 或更高版本的 WebSphere Application Server V7.0。


多安全域业务场景

图 1 是一个 Web 服务联合业务场景示例。图中显示三个 WebSphere Application Server 安全域,每个安全域包含自己的用户存储库配置。这些安全域可以代表不同的业务单位或不同的公司。左边两个安全域中的用户发送 Web 服务消息以访问右边安全域的资源。用户在 SAML 令牌中发送他们的身份,向目标安全域指出自己的身份。Web 服务提供者使用 SAML 用户身份创建安全上下文;例如 JAAS 主体。做出资源访问控制决策需要代表客户机的 JAAS 主体。

图 1. 跨 WebSphere Application Server 安全域断言 SAML 令牌
图 1. 跨 WebSphere Application Server 安全域断言 SAML 令牌

如果这三个安全域共享一个公用用户目录,那么 Web 服务提供者只需把接收的 SAML 令牌的主体身份映射到本地用户目录中的用户条目,就可以创建代表请求者的 JAAS 主体。如果这三个安全域并不共享公用用户目录,Web 服务提供者仍然可以把接收的 SAML 主体身份映射到本地用户目录中的用户条目,但是需要配置本地用户目录。如果安全域代表单独的公司或业务单位,每个安全域很可能有自己的用户目录。对于外部安全域和外部用户目录中的每个用户身份,管理员可以在本地用户目录中创建一个具有相同身份的条目,这基本上是一对一映射配置。管理员也可以把外部安全域中的所有用户身份映射到本地用户目录中的单一用户条目,这是多对一映射。在更一般的情况下,管理员可以设置多对多映射,把外部用户身份和组映射到本地用户目录中的某些用户身份和组。

设置用于身份映射的身份和组很繁琐,还会产生一种有意思的副作用。如果某人使用原本只用于身份映射的用户 ID 向本地安全域验证身份,那么会发生什么呢?另外,随着安全域数量增加,映射配置很可能会变得更复杂。对于业务审计来说,也希望知道访问资源的原用户。稍后介绍的一种方法可以完全避免身份映射,可以自然地保留原来的用户身份。

本文利用 WebSphere Application Server 的 多安全域 特性。一个安全域包含一套单独的安全策略和配置数据,其中包括用户存储库配置。WebSphere Application Server 允许在一个计算单元中配置多个安全域。如果启用全局安全性,可以配置至少一个安全域作为管理安全域,再在同一计算单元中配置零个或多个应用安全域。管理安全域由管理子系统使用,包括部署管理器、节点代理和管理控制台应用程序。如果没有定义应用安全域,管理安全域还作为应用服务器的默认安全域。应用服务器可以连接应用安全域,服务器上部署的所有应用程序都使用这个安全域。

多个安全域提供更好的应用程序和用户隔离。可信身份验证领域 (TAR) 机制提供一种安全、简便的方法,可以管理来自外部安全域的用户和应用程序以及对本地安全域中资源的访问,其前提条件是外部安全域是本地安全域所信任的。外部安全域用户会保留其身份,不需要针对本地用户目录检验他们。WebSphere Application Server V7.0 实现通过 RMI/IIOP CSIv2 协议支持 LTPA 安全令牌和 EJB 资源访问。WebSphere Application Server SAML 特性扩展了 TAR 机制,支持通过 Web 服务安全协议和 SAML 安全令牌访问资源。

实际上,只要 SAML 令牌是由 Web 服务提供者所信任的令牌颁发者颁发的,Web 服务提供者就可以接受来自外部安全域的 Web 服务请求。使用 SAML 令牌中的身份和组属性来创建 JAAS 主体。不需要通过访问本地目录查找任何本地用户身份和属性。可以把可信外部安全域用户身份和组直接分配给本地安全角色。这种机制不涉及配置本地用户目录,因此显著简化了访问控制配置。但是,Web 服务提供者如何检查信任关系呢?

可以通过配置 WebSphere Application Server 中的 SAML 特性在三个点上执行信任关系检查。应用服务器可以检查:

  • SAML 令牌颁发者的数字签名是否有效,从而检查令牌的真实性。
  • 特定的颁发者是否确实可信,从而对用户身份进行 SAML 断言。
  • 特定的颁发者是否代表可信的安全域,即是否允许这个安全域中的用户进入目标安全域。

检查信任关系之后,Web 服务提供者可以对接收的 SAML 令牌执行断言,从而使用 SAML 令牌颁发者名称、用户身份和可选的组成员关系属性在安全上下文中创建客户机调用者主体。安全上下文的创建基于信任关系,所以应用服务器不需要针对本地安全域的用户存储库检查 SAML 用户身份。这种基于信任关系的方法不需要在本地用户存储库中定义或映射外部安全域的用户。

如果涉及的所有安全域都是 WebSphere Application Server,那么可以完整地使用策略配置来设置跨安全域的 SAML 断言和访问控制,不需要其他代码。但是,WebSphere Application Server 也支持发起请求的安全域或 SAML 令牌颁发者不是 WebSphere Application Server(或任何 IBM 产品)的场景。SAML 规范没有指定组属性名,所以 WebSphere Application Server 可以配置为使用任何 SAML 属性代表用户身份和组。如果目标安全域不是 WebSphere Application Server,根据具体产品不同,可能可以通过配置或定制代码设置三个信任关系检查,但是这种配置超出了本文的范围。

可以按两种方法之一使用策略集和绑定配置把包含外部安全域身份和组的客户机调用者主体传播给下游的 Web 服务:

  • 可以把 Web 服务请求中 原来的 SAML 令牌传播 到 WebSphere Application Server,在这种情况下将应用相同的信任关系检查。
  • 也可以在 Web 服务消息 中传播整个客户机 RunAs 主体,RunAs 主体中已经包含接收到的 SAML 令牌。

作为最佳实践,对于 Web 服务客户机和 Web 服务提供者之间的消息交换应该采用传输级保护(例如 SSL),或者采用消息级加密和签名,或者同时采取这两种保护机制。图 1 中使用蓝色的锁图标表示消息保护。SAML 令牌中的所有信息(包括用户身份和属性)必须由 SAML 令牌颁发者执行数字签名。图 1 中使用红色的锁图标表示 SAML 令牌由颁发者签名。尽管本文假设所有安全域都由基于 WebSphere Application Server 的系统组成,但是也可以对其他应用服务器应用这种技术。下一节介绍 WebSphere Application Server SAML 断言信任模型。强烈建议配置其他厂商的应用服务器或编写代码,从而相应地实施信任关系检查。


信任模型

WebSphere Application Server 可以配置为根据与 SAML 令牌颁发者的信任关系断言 SAML 令牌。在创建安全上下文以断言 SAML 令牌时,应用服务器不需要针对本地用户存储库检验 SAML 身份。WebSphere Application Server 信任模型在前面提到的三个信任关系检查点上执行信任关系检查。信任关系检查的基础是 SAML 令牌由颁发者执行数字签名。

图 2 所示的示例 SAML 2.0 发送者令牌包含整个 SAML 令牌的数字签名。在对 SAML 令牌执行签名时,必须使用封装的签名,这意味着嵌入的签名覆盖整个 SAML 令牌。数字签名 ds:Reference URI 属性引用 SAML 令牌 ID _93B335BAA1D8B8811A1257438450816。SAML 令牌的颁发者使用自己的私钥签名 SAML 令牌,在令牌中包含相应的 X.509 证书。图中的 SAML 令牌图标包含一个证书图标,这表示 SAML 令牌中嵌入的颁发者证书。Web 服务提供者可以使用嵌入的证书中的公钥检查颁发者数字签名的完整性,使用嵌入的证书检查颁发者是否值得信任。

图 2. 由颁发者执行数字签名的示例 SAML 2.0 发送者令牌
图 2. 由颁发者执行数字签名的示例 SAML 2.0 发送者令牌
  • 第一个信任关系检查点

    第一个检查点检查颁发者签名证书是否确实是应用服务器所信任的 SAML 令牌颁发者。应用服务器根据配置的信任存储中的证书检查接收到的证书。然后,应用服务器使用检查过的颁发者签名证书中的公钥检查 SAML 令牌数字签名,从而检查接收到的令牌的完整性。数字签名检查确认接收到的 SAML 令牌中的信息没有被篡改过。

    在这个检查点上,应用服务器确保它只接受来自可信颁发者的 SAML 令牌。

  • 第二个信任关系检查点

    可以把应用服务器配置为针对策略集绑定配置检查 SAML 令牌颁发者名称属性和包含的签名证书。为了实现最优结果,应该在策略集绑定配置中指定证书所有者名称和 SAML 令牌颁发者名称,让应用服务器可以在签名证书和颁发者名称之间建立联系。这样,应用服务器可以检查由某个令牌颁发者(由指定的签名证书表示)签名的 SAML 令牌的颁发者名称是否与策略集绑定配置中定义的颁发者名称一致。在默认情况下,应用服务器使用 SAML 令牌颁发者名称代表外部安全域。具体地说,应用服务器检查颁发者是否确实可信,从而只接受来自特定安全域的用户。

    这个检查点对于维护应用服务器运行时完整性很重要;当某个 SAML 令牌颁发者被破解时,它确保损害只限于来自这个安全域的用户,不会扩散到属于其他安全域的用户。

  • 第三个信任关系检查点

    应用服务器检查外部安全域是否可信。具体地说,SAML 令牌颁发者名称确实在入站可信身份验证领域列表中定义了。应用服务器有一个信任任何外部安全域的配置选项。为了实现最优结果,应该在可信身份验证领域列表中显式地指定可信外部安全域。

    在这个检查点上,应用服务器确保只对可信外部安全域中的用户允许 SAML 令牌断言。

主体确认方法考虑因素

WebSphere Application Server 支持 OASIS Web Services Security SAML Token Profile 1.1 Specification,支持发送者主体确认方法和密钥持有者主体确认方法:

  • 密钥持有者主体确认方法要求整个 SAML 令牌由颁发者执行数字签名,还有其他安全需求。
  • 发送者主体确认方法不要求应用服务器执行 SAML 令牌数字签名。

在默认情况下,应用服务器检查 SAML 令牌是否按照两种确认方法的要求签名。检查 SAML 令牌数字签名和签名证书是 SAML 令牌断言信任模型的基础,信任模型应用于发送者 SAML 令牌和密钥持有者 SAML 令牌。对于密钥持有者主体确认,SAML 令牌在密码学意义上与包含它的 SOAP 消息相关联。因此,Web 服务客户机使用 SAML 令牌中定义的密钥对 SOAP 请求消息执行数字签名。因此,Web 服务接收者可以检查 Web 服务客户机是否确实知道密钥,以此确认它拥有 SAML 令牌。使用密钥持有者 SAML 令牌可以提高消息和 SAML 令牌保护的强度,但是并不影响 SAML 令牌断言信任模型。


断言 SAML 令牌

当通过 SAML 令牌断言创建安全上下文时,应用服务器运行时代码需要 SAML 令牌中的外部安全域名、用户身份和(可选的)用户组成员关系数据。

应用服务器运行时从经过检验的 SAML 令牌中提取出 SAML 令牌颁发者名称,使用它作为外部安全域身份验证领域名(图 3)。

图 3. SAML 2.0 颁发者断言示例
图 3. SAML 2.0 颁发者断言示例

在默认情况下,对于 SAML 1.1 令牌,用户安全名称是 NameIdentifier 断言(图 4);对于 SAML 2.0 令牌,是 NameID 断言(图 5)。也可以把其他 SAML 属性配置为用户安全名称。

图 4. SAML 1.1 NameIdentifier 示例
图 4. SAML 1.1 NameIdentifier 示例
图 5. SAML 2.0 NameID 示例
图 5. SAML 2.0 NameID 示例

SAML 规范没有指定标准的组成员关系属性。应用服务器提供的 策略集绑定配置 可以指定应该使用哪个 SAML 属性定义组成员关系(如果有的话)。SAML 1.1 和 SAML 2.0 AttributeStatement 断言中定义的组成员关系示例见图 6 和图 7。

图 6. SAML 1.1 组成员关系属性示例
图 6. SAML 1.1 组成员关系属性示例
图 7. SAML 2.0 组成员关系属性示例
图 7. SAML 2.0 组成员关系属性示例

SAML 1.1 示例在 AttributeAssertion 元素中包含一个 Subject 断言。只有 SAML 1.1 规范要求这么做。

对于前面的示例,安全上下文中的客户机调用者主体包含以下用户信息:

  • Realm name: acme.com
  • Security name: Alice
  • Unique ID: acme.com/Alice
  • Unique group ID 1: acme.com/Acme employee
  • Unique group ID 2: acme.com/Gold membership

跨 WebSphere Application Server 安全域断言

下载 部分包含一个示例 Web 服务客户机应用程序和 Web 服务提供者应用程序,它们演示如何设置策略集、绑定和可信身份验证领域配置以实现跨安全域 SAML 令牌断言。图 8 显示示例应用程序涉及的解决方案部分(蓝色圈中的部分)。

图 8. 跨安全域 SAML 令牌断言
图 8. 跨安全域 SAML 令牌断言

示例应用程序是自包含的,可以很简便地运行它。通常,在联合 Web 服务资源(后面讨论)时,使用 Security Token Service (STS) 验证用户的身份并把 SAML 令牌颁发给经过授权的用户。示例应用程序并不依赖于外部 STS,而是利用 WebSphere Application Server SAML Token Factory API 创建 SAML 令牌(在本文中称为自颁发的 SAML 令牌)。为了演示跨安全域 SAML 令牌断言,示例应用程序需要区分至少两个安全域。为了演示跨安全域断言,常常必须配置两个应用服务器,每个服务器在一个单独的安全域中。为了简化这个示例的配置,示例应用程序在单一应用服务器上演示跨安全域行为。在创建自颁发的 SAML 令牌时,示例应用程序通过设置 SAML 令牌颁发者属性表示外部安全域。因此,SAML 令牌中的用户和组信息代表外部安全域中的用户,而不是本地用户存储库中定义的用户。图 9 说明示例应用程序的元素。

图 9. 示例应用程序使用自颁发的 SAML 令牌演示跨安全域 SAML 断言
图 9. 示例应用程序使用自颁发的 SAML 令牌演示跨安全域 SAML 断言

除了编写定制的代码之外,另一种方法是通过配置策略集绑定从安全上下文中的 RunAs 主体生成 SAML 令牌。当从 RunAs 主体创建自颁发的 SAML 令牌时(而且 RunAs 主体尚未包含 SAML 令牌),WebSphere Application Server V7 Fix Pack 7 实现从 RunAs 主体中的 WSCredential 对象中提取出用户身份,但是并不在 SAML 令牌中插入组成员关系信息。因此,本文采用定制代码方式,通过程序从 WSCredential 对象中提取出组信息并插入 SAML 令牌。

如图 9 所示,浏览器用户使用基于表单的登录向示例应用程序验证身份。Web 浏览器用户需要输入用户名和密码,向本地用户存储库验证身份。Web 服务客户机应用程序使用用户身份生成自颁发的 SAML 令牌,但是使用一个预先配置的安全域领域名作为令牌颁发者和组成员关系数据。Web 服务客户机通过发送包含自颁发 SAML 令牌的 SOAP 消息来调用 EJBWSProviderApp Web 服务。用一个密钥对 SAML 令牌执行签名,这个密钥是 EJBWSProviderApp Web 服务提供者所信任的。EJBWSProviderApp Web 服务提供者在三个信任关系检查点上检查信任关系。EJBWSProviderApp 是一个 EJB 3.0 bean,使用 JAX-WS 编程模型把它公开为 Web 服务。选用 EJB Web 服务实现是为了演示如何设置授权策略,以及如何检查访问控制决策中使用的 SAML 断言。

清单 1 中的代码片段说明示例 Web 服务客户机如何生成自颁发的 SAML 2.0 令牌。

清单 1
1. package com.ibm.wss.sample.ejbws;

2. import java.util.ArrayList;

3. import javax.security.auth.Subject;
4. import javax.servlet.ServletException;

5. import com.ibm.websphere.security.auth.WSSubject;
6. import com.ibm.websphere.security.cred.WSCredential;
7. import com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory;
8. import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
9. import com.ibm.wsspi.wssecurity.saml.config.CredentialConfig;
10. import com.ibm.wsspi.wssecurity.saml.config.ProviderConfig;
11. import com.ibm.wsspi.wssecurity.saml.config.RequesterConfig;
12. import com.ibm.wsspi.wssecurity.saml.data.SAMLAttribute;
13. import com.ibm.wsspi.wssecurity.saml.data.SAMLNameID;

14. public class SamlTokenGenerator {
	
15.	public static SecurityToken getSamlToken() throws
16.    ServletException 	
17.   {
18.		SecurityToken samlToken = null;
19.		String name = getPrincipal();
20.		String[] groups = getGroups();
21.		String localRealm = getRealm();
		
22.		System.out.println("SAML principal name: " + name);
23.		try {

24.			SAMLTokenFactory samlFactory =
25.                SAMLTokenFactory.getInstance("http://docs.oasis
26.        -open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0");
			
27.			RequesterConfig reqData =
28.                      samlFactory.newBearerTokenGenerateConfig();

29.			CredentialConfig cred =
30.                         samlFactory.newCredentialConfig();
31.			reqData.setAuthenticationMethod("Password");   
32.               //Password is the authentication method
			
33.			//create SAML NameID or NameIdentifer using principal
34.               //    in Caller Subject
35.			SAMLNameID nameID = null;
36.			nameID = new
37.                       SAMLNameID(name,null,localRealm,null,null);
38.			cred.setSAMLNameID(nameID);
			
39.			//Create SAML Attributes using group memberships 
40.               //    in Caller Subject
41.			if (groups!= null && groups.length >0){
42.				ArrayList<SAMLAttribute> al = new
43.                             ArrayList<SAMLAttribute>();				
44.				SAMLAttribute sattribute = new
45.                        SAMLAttribute("Membership", groups, 
46.                        null,null /* format*/, null, null  );
47.				al.add(sattribute);
48.				cred.setSAMLAttributes(al);
49.			}
50.			ProviderConfig samlIssuerCfg =
51.                 samlFactory.newDefaultProviderConfig("acme.com");   
52.                  //acme.com is issuer name
53.			samlToken = samlFactory.newSAMLToken(cred, reqData,
54.                   samlIssuerCfg);
55.		} catch(Throwable e) {
56.			System.out.println("testNewSecurityTokenV1Bearer:
57.                caught exception: "+e.getMessage() + "\n");
58.			e.printStackTrace(System.out); 
59.		}
59.		return samlToken;
60.	}
61.	
62.	private static String getPrincipal(){
63.		String name = null;
64.		String realm = null;
65.		try {
66.			Subject subject = WSSubject.getRunAsSubject();
67.			WSCredential credential = null;
68.
69.	    	   if (subject != null ) {
70.	        	java.util.Set<Object> publicCreds =
71.                 subject.getPublicCredentials();
72.	            if (publicCreds != null && publicCreds.size() > 0)
73.	            {
74.	                java.util.Iterator<Object> publicCredIterator =
75.                      publicCreds.iterator();
76.	                while (publicCredIterator.hasNext())
77.	                {
78.	                    Object cred = publicCredIterator.next();
79.	                    if (cred != null && cred instanceof
80.                           WSCredential)
81.	                    {
82.	                       credential = (WSCredential) cred;
83.	                       name = credential.getSecurityName();
84.	                       realm = credential.getRealmName();
85.	                       break;
86.	                    }
87.	                }      
88.	            }
89.	    	   }  
90.	    	   
91.	    	   if (name != null && (name.contains(realm))){
92.	    		name =
93.               name.substring(name.indexOf(realm)+realm.length()+1);
94.	    	   }
95.		} catch (Exception e){
96.			name="UNAUTHENTICATED";
97.		}
98.		return name;
99.	}
	
100.	private static String [] getGroups() throws ServletException {
101.		String []grps = null;
102.		try {
103.	       	WSCredential credential = null;
104.	       	Subject subject = null;
105.	       	ArrayList groups = new ArrayList();
106.	    	   try {
107.	    		subject = WSSubject.getRunAsSubject();
108.	    	   } catch (Exception ex) {
109.	    		System.out.println("Exception caught upon invoking
110.                WSSubject.getCallerSubject():" + ex.getMessage());
111.	    		ex.printStackTrace(System.out);
112.	    		throw new ServletException(ex.getCause());
113.	    	   }
114.	    	   if (subject != null ) {
115.	        	java.util.Set<Object> publicCreds =
116.                 subject.getPublicCredentials();
117.	            if (publicCreds != null && publicCreds.size() > 0)
118.	            {
119.	                java.util.Iterator<Object> publicCredIterator =
120.                      publicCreds.iterator();
121.	                while (publicCredIterator.hasNext())
122.	                {
123.	                    Object cred = publicCredIterator.next();
124.	                    if (cred != null && cred instanceof
125.                              WSCredential)
126.	                    {
127.	                       credential = (WSCredential) cred;
128.	                       break;
129.	                    }
130.	                }
131.	            }
132.	    	   }
133.	    	   if (credential != null){
134.	    		groups = credential.getGroupIds();	    	
135.	    	   }

136.	    	   if (groups != null && groups.size() >0){
137.		    	String realm = credential.getRealmName();
138.	    		grps = new String[groups.size()]  ;
139.	    		groups.toArray(grps);
140.	    		for (int i=0; i<groups.size();){
141.	    			String name = grps[i];
142.	    	    	   if (name != null && name.contains(realm)){
143.	    	    		name =
144.              name.substring(name.indexOf(realm)+realm.length()+1);
145.	    	    		grps[i] = name;
146.	    	    	   }
147.	    	    	   i++;
148.	    		}
149.	    	   }
150.		} catch (Exception e){
151.    	   System.out.println("Exception caught populating groups:" 
152.                + e.getMessage());
153.    	   e.printStackTrace(System.out);
154.    	   throw new ServletException(e.getCause());
155.		}
156.		return grps;
157.	}
	
158.	private static String getRealm() throws ServletException{

159.		String realm = null;
160.		try {
161.			Subject subject = WSSubject.getRunAsSubject();
162.			WSCredential credential = null;
163.
164.	    	   if (subject != null ) {
165.	        	java.util.Set<Object> publicCreds =
166.                subject.getPublicCredentials(); 
167.	            if (publicCreds != null && publicCreds.size() > 0)
168.	            {
169.	                java.util.Iterator<Object> publicCredIterator =
170.                     publicCreds.iterator();
171.	                while (publicCredIterator.hasNext())
172.	                {
173.	                    Object cred = publicCredIterator.next();
174.	                    if (cred != null && cred instanceof
175.                          WSCredential)
176.	                    {
177.	                       credential = (WSCredential) cred;
178.	                       realm = credential.getRealmName();
179.	                       break;
180.	                    }
181.	                }
182.	            }
183.	    	   }  		
184.		} catch (Exception e){
185.		   System.out.println("Exception caught retrieving realm:"
186.               + e.getMessage());
187.    	   e.printStackTrace(System.out);
188.    	   throw new ServletException(e.getCause());
189.		}
190.		return realm;
191.	}
192. }

在清单 1 中:

  • 在第 24-26 行上创建 SAMLTokenFactory 实例以生成 SAML 2.0 令牌。
  • RequestConfig 对象指定新令牌的需求。
  • 第 27-28 行上的 newBearerTokenGenerateConfig() 调用指定令牌应该需要发送者主体确认方法。
  • 第 50-51 行把 SAML 令牌颁发者名称设置为 acme.com
  • 使用颁发者名称表示安全域的名称。
  • 第 35-38 行中的代码设置用户身份。
  • 第 41-49 行添加组成员关系 SAML 属性。
  • 第 53-54 行生成一个用于测试的 SAML 2.0 令牌,其中包含发送者信息以及用户身份和属性。
  • 在第 62 行上,getPrincipal() 方法从 RunAs 主体中提取出用户安全名称。如果 UserRegistry getSecurityName() 方法返回的名称包含 realm/ 前缀,getPrincipal() 方法就删除它。
  • 在第 100 行上,getGroups() 方法从 RunAs 主体中提取出用户组。在 WebSphere Application Server 中,组信息的格式是 "group:<realm>/group_name"。当提取组名时,getGroups() 方法删除前缀 "group:<realm>/"。
  • 在第 158 行上,getRealm() 方法从 RunAs 主体中提取出领域属性。

将对新令牌执行签名。代码并没有显式地指定应该对新令牌执行签名,因为这里的代码使用默认的令牌颁发者属性生成新令牌。第 36 行上创建的 ProviderConfig 对象包含 SAMLIssuerConfig.properties 文件中指定的默认属性。图 12 给出应用程序的示例 SAMLIssuerConfig.properties 文件。属性文件定义默认的密钥存储、用于打开密钥存储的密码和用于 SAML 令牌签名的私钥。这些是最初在 ProviderConfig 对象中设置的默认值。可以使用 ProviderConfig 接口修改任何属性。(关于 SAML Token Factory API 的更多信息,参见 WebSphere Application Server Information Center。)

在 $install_root/profiles/$PROFILE/config/cells$/CELLNAME/sts 目录中可以找到计算单元级属性文件的拷贝。可以在服务器级定义属性文件。(更多信息参见 WebSphere Application Server Information Center。)

通常,设置了策略集之后,Web 服务安全运行时环境会从安全上下文中的 RunAs 主体中提取出用户身份信息,从而创建并发送 SAML 令牌。不需要编写定制的代码。但是,对于本示例,希望模拟在外部安全域中创建的 SAML 令牌。因此,必须通过程序生成一个自颁发的 SAML 令牌并把它注入 Web 服务安全运行时环境中,从而禁用使用 RunAs 主体生成 SAML 令牌的默认行为。清单 2 中的代码实现这个目标。代码把自颁发的 SAML 令牌保存在 AxisService RequestContext 中。当找到 SAML 令牌时,Web 服务安全运行时环境在下游消息中传播 RequestContext 中的令牌。

清单 2
43. SAMLToken samlToken = <self-issued SAML tokens previously generated>; 
44. 
45. Map<String, Object> requestContext = ((BindingProvider) 
46.                                   servicePort).getRequestContext(); 
47. 
48. requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, serviceURL); 
49. //Put the samlToken into RequestContext 
50. requestContext.put( 
51. com.ibm.wsspi.wssecurity.saml.config.SamlConstants.SAMLTOKEN_IN_MESSAGECONTEXT, 
    samlToken);

示例应用程序的 Web 服务提供者端很简单。Web 服务提供者端演示如何使用 SAML 断言做出访问控制决策,但是不需要定制的代码。

配置应用服务器

本节提供设置示例应用程序、策略集和绑定配置的步骤。这些说明假设您已经熟悉通过配置策略集和绑定使用 SAML 令牌的过程。更多信息参见 WebSphere Application Server Information Center参考资料 中列出的 JAX-WS 文章。

要想运行本文的示例应用程序和学习以下几节,需要对应用服务器执行一些配置:

  1. 安装 WebSphere Application Server Version 7.0 Fix Pack 7 或更高版本
  2. 下载并安装 下载 部分中的示例 Web 服务客户机应用程序和 Web 服务提供者应用程序。
  3. 这些说明 从默认策略存储库导入 SAML 2.0 Bearer WSHTTPS default 策略集(图 10)。这个策略集要求 Web 服务客户机用发送者主体确认方法发送 SAML 2.0 令牌,并用 SSL 保护消息。
    图 10. 从默认存储库导入 SAML 2.0 Bearer WSHTTPS default 策略集
    图 10. 从默认存储库导入 SAML 2.0 Bearer WSHTTPS default 策略集
  4. 假设启用了 WebSphere Application Server 全局安全性,配置可信的外部安全域。最简单的方法是使用 Security Configuration 向导启用管理安全性。还需要启用应用程序安全性,让示例应用程序可以使用安全上下文中经过身份验证的用户主体创建 SAML 令牌。这个步骤涉及在 Web 服务提供者端上配置第三个信任关系检查点。使用应用服务器模拟目标安全域 Web 服务提供者需要这个步骤。WebSphere Application Server V7.0 身份验证子系统支持断言包含外部领域名的用户身份,它根据入站可信身份验证领域列表检查外部领域名。完成这个配置步骤之后,WebSphere Application Server 可以用外部安全域中的用户身份创建客户机调用者主体。

    完成配置全局安全性的步骤之后,按以下步骤配置可信安全域:

    1. 在 Global Security 面板上,单击 Configure beside Available realm definitions
    2. 单击 Trusted authentication realms - inbound
    3. 选择 Trust realms as indicated below(图 11)。
    4. 单击 Add External Realm
    5. 在 External realm name 中添加 SAML 令牌颁发者名称。SAML 令牌颁发者名称提供 SAML 令牌的颁发者的相关信息,这一信息在 SAML 2.0 令牌的 <Issuer> 元素或 SAML 1.1 令牌的 Issuer 属性中。对于这个示例,添加 acme.com 作为可信外部领域,见图 11。
      图 11. 把 SAML 令牌颁发者 acme.com 定义为可信身份验证领域
      图 11. 把 SAML 令牌颁发者 acme.com 定义为可信身份验证领域
    6. 在您的用户存储库中创建用户名 Alice 和密码。在这个测试中,内置的联合存储库作为用户存储库。使用应用服务器模拟发起请求的安全域 Web 服务客户机需要这个步骤。在用户存储库中添加用户 Alice 是必需的,这样才能使用浏览器向受保护的示例应用程序验证身份并访问它。在这个示例中,联合的用户存储库作为本地用户存储库,默认的领域名是 defaultWIMFileBasedRealm。示例应用程序接受一个经过身份验证的用户身份,用它创建 SAML 令牌并把令牌颁发者设置为 "acme.com",以此模拟跨安全域断言。必须启用应用程序安全性,让安全运行时对应用程序实施安全约束,并把经过身份验证的用户身份放在安全上下文中。
    7. 把示例密钥存储文件和示例信任存储文件解压到安装示例应用程序的概要文件下面的 etc\ws-security\samples 目录中。密钥存储密码是 storepass,密钥密码是 keypass。示例密钥存储文件 saml-provider.jceks 包含 RSA 私钥以及相应的 X.509 证书和 RSA 公钥。密钥存储文件用于对自颁发的 SAML 令牌执行数字签名。信任存储文件 recipient.jceks 包含相同的 X.509 证书,Web 服务接受者使用它检查 SAML 令牌的真实性。可以使用 WebSphere Application Server 附带的 keytool 命令生成密钥存储(清单 3)。
      清单 3
      keytool -genkey -alias samlissuer -keystore saml-provider.jceks -dname 
         "CN=SAMLIssuer, O=ACME" -storepass storepass -keypass keypass -storetype 
         jceks -validity 5000 -keyalg RSA

      使用以下命令把颁发者证书导出到 issuerpub.cert 文件中,然后创建信任存储文件 recipient.jceks:
      清单 4
      keytool -export -alias samlissuer -file issuerpub.cer -keystore 
      	saml-provider.jceks -storepass storepass -storetype jceks
      
      keytool -import -alias samlissuer -file issuerpub.cer -keystore 
      	recipient.jceks -storepass storepass -storetype jceks 
      	-keypass keypass –oprompt

      实际上,可以使用 saml-provider.jceks 文件同时作为密钥存储文件和信任存储文件,因为 saml-provider.jceks 包含颁发者 X.509 证书,还因为这个示例使用单一应用服务器。在一般情况下,如果在两个安全域中的两个应用服务器上运行示例 Web 服务客户机和 Web 服务提供者,就应该创建包含颁发者 X.509 证书但不包含私钥的信任存储文件。
    8. 编辑位于 $install_root/profiles/$PROFILE/config/cells$/CELLNAME/sts 的配置文件 SAMLIssuerConfig.properties,设置密钥存储和信任存储。当创建自颁发的 SAML 令牌时,SAML 令牌工厂使用这个属性文件中的密钥存储和其他配置数据对 SAML 令牌执行签名。当通过程序检查 SAML 令牌时,信任存储文件配置作为 SAML 令牌工厂使用的默认值。修改后的属性文件应该与图 12 相似。
      图 12. 示例 SAMLIssuerConfig.properties 文件
      图 12. 示例 SAMLIssuerConfig.properties 文件
    为了演示,示例应用程序包含 SAML samlbearerAssertProvider 和 samlbearerAssertionClient 绑定示例。这两个一般绑定示例是通过复制并修改 WebSphere Application Server 附带的一般绑定示例 Saml Bearer Provider Sample 和 Saml Bearer Client Sample 创建的。稍后会看到如何创建这两个绑定文件。基本上,需要把 Saml Bearer Client Sample 改为生成自颁发的 SAML 令牌,而不是向外部 STS 请求 SAML 令牌。还需要把 Saml Bearer Provider Sample 一般绑定改为选用 SAML 令牌代表调用者身份并启用跨安全域断言。您不必自己创建这些绑定,可以按照下一步中的说明导入示例绑定。
  5. 导入示例客户机一般绑定的步骤是,把示例应用程序包含的绑定文件解压到一个临时目录中,然后使用 importBinding 命令脚本或管理控制台中的 Import 按钮把它们导入应用服务器中。用临时目录中的 .../bindings/samlbearerAssertionClient 目录结构创建一个路径。

配置 Web 服务客户机

为了创建所需的一般客户机绑定(只在选择导入 samlbearerAssertionClient 绑定示例的情况下),执行以下步骤并修改 Saml Bearer Client Sample:

  1. 登录管理控制台。
  2. 在左边的导航栏中选择 Services
  3. 展开 Policy sets 并选择 General client policy set bindings
  4. 在 General client policy set bindings 对话框中,选择 Saml Bearer Client sample,然后单击集合表格中的 Copy。输入您选择的名称;例如 samlbearerAssertionClient
  5. 关于配置 SAML 2.0 发送者令牌的客户机和提供者绑定的信息,参见 WebSphere Application Server Information Center。删除四个定制的 SAML 令牌生成器回调处理器属性:stsURI、wstrustClientPolicy、wstrustClientBinding 和 wstrustClientSoapVersion。示例应用程序使用自颁发的 SAML 令牌,不需要这些属性;但是,当向外部 STS 请求 SAML 令牌时,需要这些属性。图 13 给出完成后的客户机一般绑定。
图 13. 示例 Web 服务客户机绑定
图 13. 示例 Web 服务客户机绑定

配置 Web 服务提供者

  1. 为了创建所需的一般服务器绑定(同样,只在选择导入 samlbearerAssertionProvider 绑定示例的情况下),执行以下步骤,复制并修改 Saml Bearer Provider Sample:
    1. 登录管理控制台。
    2. 在左边的导航栏中选择 Services
    3. 展开 Policy sets 并选择 General provider policy set bindings
    4. 在 General provider policy set bindings 对话框中,选择 Saml Bearer Provider sample,然后单击集合表格中的 Copy。输入您选择的名称;例如 samlbearerAssertProvider
    5. 关于配置 SAML 发送者令牌的客户机和提供者绑定的信息,参见 WebSphere Application Server Information Center。把令牌消费者定制回调 trustStorePath 和 trustStorePassword 属性的属性值替换为 cecipiens.jceks 的值。图 14 给出完成后的提供者一般绑定。
      图 14. 示例 Web 服务提供者绑定
      图 14. 示例 Web 服务提供者绑定
      图 14 所示的信任存储配置对应于第一个信任关系检查点。SAML 令牌消费者针对 recipient.jceks 中的证书检验 SAML 令牌颁发者数字签名和签名证书。

      执行下一个步骤配置第二个信任关系检查点。一定要通过配置 Web 服务绑定显式地列出可信的 SAML 颁发者和相应的证书,从而确保包含指定证书的 SAML 令牌只能断言指定颁发者安全域中的用户凭证。换句话说,SAML 令牌消费者检查接收到的 SAML 令牌中的颁发者名称是否与配置的 trustedIssuer 匹配,以及颁发者 X.509 证书所有者名称是否与配置的 trustedSubjectDN 匹配。

    6. 添加定制属性 trustedIssuer_n 和 trustedSubjectDN_n,前者定义可信的 SAML 颁发者名称,后者定义可信的 X.509 证书(其中的 _n 是从 1 开始的整数,对于每个颁发者递增 1)。配置 trustedIssuer_ 和 trustedSubjectDN_ 属性(尽管它们是可选的)。如果没有指定 trustedIssuer 属性,令牌消费者就不会检验 SAML 令牌中的颁发者名称。如果没有指定 trustedSubjectDN 属性,令牌消费者就不会检验接收到的颁发者 X.509 证书的所有者字段。图 15 给出可信颁发者配置的绑定示例。
      图 15. 包含 SAML 令牌颁发者检查的示例 Web 服务提供者绑定
      图 15. 包含 SAML 令牌颁发者检查的示例 Web 服务提供者绑定
  2. 添加更多可信伙伴。

    可以通过递增整数 n 添加更多可信的颁发者。例如,图 16 显示两个可信颁发者。后缀数字 _n 必须是连续的。如果删除一对属性,比如 trustedIssuer_m 和 trustedSubjectDN_m,那么必须把从 _m+1 到 _n 的条目下移一位。在序列中留下间隙会导致令牌消费者处理错误。

    图 16. 配置另一个可信外部安全域
    图 16. 配置另一个可信外部安全域
  3. 为跨域 SAML ID 断言配置 Web 服务调用者绑定。

    进入 Caller 面板,单击 New,在 Caller identity local part 中添加作为调用者令牌的 SAML 令牌。在这个示例中,添加 http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0 作为调用者身份本地部分。

    1. 添加回调处理器:com.ibm.websphere.wssecurity.callbackhandler.SAMLIdAssertionCallbackHandler
    2. 添加回调处理器定制属性 crossDomainIdAssertion 并把它的值设置为 true。如果不定义这个属性,Web 服务安全运行时的默认行为是执行本地身份断言,把 SAML 令牌用户身份映射到当前安全域的用户存储库中的用户条目。如果定义了 crossDomainIdAssertion 属性并设置为 true,Web 服务安全运行时会断言 SAML 令牌用户身份和组属性,创建一个代表此用户的调用者 JAAS 主体。在这种情况下,Web 服务安全运行时并不访问当前安全域的用户存储库。
    3. 还可以添加回调处理器定制属性 groupName_n(其中的 n 是递增 1 的正整数)以指定 SAML 组名称。这个属性很有用,因为 SAML 规范没有定义代表组信息的标准属性。

      例如,如果需要由 AttributeName=SecretAuthorizationGroup 定义的组成员关系,那么添加定制属性 groupName_1=SecretAuthorizationGroup。Web 服务安全运行时使用接收到的 SAML 令牌中指定的属性值填充调用者 WSCredential 对象组成员信息。如果没有定义 groupMName_n 属性,那么 WebSphere Application Server Web 服务安全实现会自动地扫描 SAML 属性断言名称 "groups"、"group"、"memberof"、"membership"、"groupmembership"、"members"、"groupid"、"role" 和 "roles",使用它们的属性值作为凭证的组成员信息。

    4. 还可以添加回调处理器定制属性 principalName_n(其中的 n 是递增 1 的正整数)以指定用作调用者身份的 SAML 令牌属性。例如,如果希望使用属性 email 作为调用者的主体,那么添加定制属性 principalName_1=email。如果没有定义 principalName_n 属性,那么 WebSphere Application Server Web 服务安全实现在默认情况下使用 SAML NameIdentifier 断言(SAML 1.1)或 NameId(SAML 2.0)作为调用者的主体名称。注意,Web 服务安全运行时把 principalName_n 和 groupName_n 与 trustedIssuer_n 和 trustedSubjectDN_n 组织在一起。换句话说,groupName_n 和 principalName_n(如果定义了)指定由特定颁发者(trustedIssuer_n)颁发的 SAML 令牌中的身份和组属性。

      图 17 给出用于断言 SAML 令牌的调用者绑定。

      图 17. 包含跨安全域设置的示例 Web 服务提供者调用者绑定
      图 17. 包含跨安全域设置的示例 Web 服务提供者调用者绑定
  4. 如果添加更多可信伙伴,可以定义更多的主体和组属性映射规则。如图 18 所示,在创建调用者主体时,使用由 bigCorp.com 颁发的 SAML 令牌中的 email 属性作为用户主体名称。
    图 18. 定义另一个主体映射规则
    图 18. 定义另一个主体映射规则

设置应用程序

  1. 在 WebSphere Application Server 上安装示例应用程序。
  2. 把示例密钥存储文件解压到安装示例应用程序的概要文件下面的 etc\ws-security\samples 目录中。密钥存储密码是 storepass,密钥密码是 keypass
  3. 连接 SAML 2.0 Bearer WSHTTPS default 策略集,然后连接客户机绑定 samlbearerAssertionClient 和服务绑定 samlbearerAssertProvider。
  4. 配置授权表,向来自可信域的外部用户授予访问权:
    1. 在管理控制台上,单击 Enterprise applications,然后单击适当的 EJB Web 服务应用程序。这个示例使用 testEJBWSProviderApp 应用程序。确保用 Java Platform, Enterprise Edition (Java EE) 安全性保护服务 EJB。testEJBWSProviderApp 应用程序是一个 EJB 3.0 应用程序,所有 EJB 方法都由安全注解定义的角色保护。
    2. 单击 Security role to user/group mapping。给可信外部领域中的用户和组分配角色。在这个示例中,给 acme.com 领域中的用户 Alice 定义安全角色 SayHelloUsers,见图 19。
      图 19. 向外部安全域的用户和组授予对 Java EE 资源的访问权
      图 19. 向外部安全域的用户和组授予对 Java EE 资源的访问权

运行示例联合 Web 服务

  1. 启动一个浏览器会话,访问这个 URL:http://localhost:9080/testEJBWSClientWeb/testEJBWSBrowserClient.jsp。
  2. 当表单登录页面出现时,输入 Alice 作为用户 ID,输入 security 作为密码,然后单击 Logon(图 20)。
    图 20. 示例应用程序的表单登录页面
    图 20. 示例应用程序的表单登录页面
  3. 根据自己的系统修改 EJB 服务 URL(最初显示 https://localhost:9443/testEJB_HTTPRouter/HelloBeanService),见图 21。需要指定 HTTPS 端口,因为 Saml Bearer WSHTTPS Default 策略集要求 SSL 传输级的消息保护。
    图 21. 示例应用程序的主服务页面
    图 21. 示例应用程序的主服务页面
  4. 如果跨域 ID 断言成功,会收到图 22 所示的消息。
    图 22. 示例应用程序的结果页面
    图 22. 示例应用程序的结果页面

Web 服务提供者由 EJB 安全角色保护。授权配置要求发出请求的用户是外部安全域 acme.com 中的 Alice。产生前面的结果就表明 SAML 令牌断言已经成功了。

假设在本地用户存储库中定义了另一个用户 Tom,½†是没有在授权表中为 Tom@acme.com 授权。当作为 Tom 再次登录时,应该会看到图 23 所示的授权错误。

图 23. 外部用户没有得到授权
图 23. 外部用户没有得到授权

联合 Web 服务资源

通过这个示例 Web 服务应用程序,您看到了如何跨安全域断言 SAML 令牌,以及如何使用断言的外部用户身份和组成员数据做出访问控制决策。可以应用这种技术跨公司和业务伙伴之间的企业边界联合 Web 服务。典型的企业环境使用 STS 向经过授权的用户颁发安全令牌。图 24 给出一个典型的业务场景。

图 24. Web 服务联合使用场景
图 24. Web 服务联合使用场景

在这个业务场景中,Web 客户机(浏览器)用户通过驻留在 WebSphere Application Server 上的公司门户应用程序访问业务服务。当访问业务伙伴的 Web 服务时,门户应用程序在 Web 服务消息的安全头中放上代表 Web 客户机的 SAML 令牌。可以把门户应用程序配置为从 Web 客户机获得身份验证数据,用这些数据向 STS 验证身份,请求 Web 客户机的 SAML 令牌。WebSphere Application Server 提供 WS-Trust 1.3WS-Trust 1.2(DRAFT 版本)的信任客户机实现,可以与外部 STS 集成。为了向 STS 验证身份,门户应用程序可以提示 Web 客户机用户输入身份验证数据。在执行最初的身份验证之后,门户应用程序可以维持与 Web 客户机的身份验证会话,使用客户机凭证向 STS 验证身份,代表客户机请求 SAML 令牌。

可用的身份验证方法包括使用身份断言、使用自颁发的 SAML 令牌和使用客户机 Kerberos 凭证。已经向 Kerberos 服务器验证身份的 Web 客户机可以使用它们的 Kerberos 凭证向门户应用程序验证身份,委托门户服务器使用它们的 Kerberos 凭证向 STS 验证身份。STS 实现必须支持 Kerberos 身份验证。WebSphere Application Server 可以根据安全上下文中的用户身份生成自颁发的 SAML 令牌。应用服务器可以使用自颁发的 SAML 令牌代表客户机向 STS 验证身份以请求 SAML 令牌,只要 STS 支持这种使用模式。对于 IBM Tivoli® Federated Identity Manager STS,门户应用程序还可以使用来自用户的 LTPA 令牌向 Tivoli STS 验证身份。

图 25 显示一个相似的场景,在这里 Web 服务客户机(Java 客户机)用户直接访问业务伙伴的 Web 服务。Web 服务客户机向 STS 验证身份以请求 SAML 令牌。他们可以使用用户 ID 和密码、Kerberos 令牌或 X.509 客户机证书,只要 STS 支持此种身份验证数据。

图 25. 访问联合 Web 服务提供者的 Web 服务客户机
图 25. 访问联合 Web 服务提供者的 Web 服务客户机

要想修改示例 Web 服务客户机绑定,让它使用外部 STS 颁发 SAML 令牌,应该指定与 STS 交互所需的 STS 端点 URL、策略集和绑定。绑定配置面板的示例见图 26。

图 26. 把 Web 服务客户机配置为使用外部 STS 颁发 SAML 令牌
图 26. 把 Web 服务客户机配置为使用外部 STS 颁发 SAML 令牌

结束语

通过使用 IBM WebSphere Application Server V7.0 Fix Pack 7 和更高版本中的 SAML 特性,可以使用 SSO 解决方案跨安全域断言 SAML 令牌。通过结合使用 SAML 断言和可信身份验证领域特性,可以使用用户身份和组成员 SAML 断言实现基于声明的资源访问控制。信任模型和三个信任关系检查点确保系统的安全性和完整性。本文提供了一个示例 EJB 3.0 JAX-WS 应用程序,演示跨安全域 SAML 断言和基于声明的访问控制。也可以应用这种技术跨企业安全域联合 Web 服务资源。本文描述的 SSO 解决方案为 Web 应用程序和 Web 服务用户提供 SSO 的便捷性,同时降低 IT 管理员的身份管理负担。


致谢

作者要感谢 Huiran Wang 开发了 EJB 3 JAX-WS 示例应用程序,感谢 Greg Truty、Hyen (Henry) Chung、Keys Botzum 和 Martin Lansche 提出了许多建设性的意见。


下载

描述名字大小
代码示例SMLfederation_sample.zip52 KB

参考资料

学习

获得产品和技术

讨论

条评论

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
ArticleID=501434
ArticleTitle=跨 WebSphere Application Server 安全域的 SAML 断言
publish-date=07222010