3.8. 保护 Jakarta XML Web 服务


WS-Security 提供了一种方法,可以保护您的服务超越传输级别协议,如 HTTPS。通过很多标准,如 WS-Security 标准中定义的标头,您可以:

  • 在服务之间传递身份验证令牌.
  • 加密消息或消息部分。
  • 签署消息.
  • 时间戳消息.

WS-Security利用了公钥和私钥加密。使用公钥加密时,用户拥有一对公钥和私钥。这些是使用大量主要编号和一个关键功能生成的。

这些键在数学上是相关的,但不能互相派生。通过这些密钥,我们可以加密消息。例如,如果 Scott 想要向 Adam 发送消息,他可以使用他的公钥加密消息。然后 Adam 可以使用他的私钥解密此消息。只有 Adam 可以解密此消息,因为他是唯一具有私钥的消息。

也可以对消息进行签名。这样,您可以确保消息的真实性。如果 Adam 想要向 Scott 发送一封消息,Scott 希望确保它来自 Adam,Adam 可以使用他的私钥签署该消息。然后,Scott 可以使用他的公钥验证消息是否来自 Adam。

3.8.1. 应用 Web 服务安全性(WS-Security)

Web 服务支持许多需要 WS 安全功能的真实场景。这些场景包括签名和加密支持,通过 X509 证书支持,通过用户名令牌进行身份验证和授权,以及 WS-SecurityPolicy 规范涵盖的所有 WS-Security 配置。

对于其他 WS-* 功能,WS-Security 功能的核心通过 Apache CXF 引擎提供。此外,JBossWS 集成还添加了一些配置增强功能,以简化启用 WS-Security 端点的设置。

3.8.1.1. Apache CXF WS-Security 实施

Apache CXF 具有支持多种配置且易于扩展的 WS-Security 模块。

系统基于为低级安全操作委派给 Apache WSS4J 的拦截器。可以通过不同的方式配置拦截器,可以通过 Spring 配置文件或直接使用 Apache CXF 客户端 API 配置拦截器。

最新版本的 Apache CXF 引入了对 WS-SecurityPolicy 的支持,该支持旨在通过策略将大部分安全配置移至服务合同中,以便客户能够从该协议中几乎可以完全自动配置。这样,用户不需要手动处理所需拦截器的配置和安装;Apache CXF WS-Policy 引擎在内部需要处理。

3.8.1.2. WS-安全政策支持

WS-SecurityPolicy 描述了与给定 WSDL 合同中公告的服务进行安全通信所需的操作。WSDL 绑定和操作引用 WS-Policy 片段与与服务交互的安全要求。WS-SecurityPolicy 规范允许指定诸如非对称和对称密钥、使用传输(HTTPS)进行加密、哪些部分或标头加密或签名、是否要包含时间戳、是否使用派生密钥或其他方面。

但是 WS-SecurityPolicy 不涵盖一些必需的配置元素,因为它们不是公开的或已发布端点合同的一部分。其中包括密钥存储位置以及用户名和密码等内容。Apache CXF 允许通过 Spring XML 描述符或使用客户端 API 或注释来配置这些元素。

Expand
表 3.4. 支持的配置属性
配置属性描述

ws-security.username

用于 UsernameToken 策略 断言的用户名。

ws-security.password

用于 UsernameToken 策略 断言的密码。如果没有指定,则会调用回调处理程序。

ws-security.callback-handler

WSS4J 安全 回调Handler,它将用于检索密钥存储和 用户名令牌的密码

ws-security.signature.properties

包含用于配置签名密钥存储和加密对象的 WSS4J 属性的属性 file/对象。

ws-security.encryption.properties

包含用于配置加密密钥存储和加密对象的 WSS4J 属性的属性 file/对象。

ws-security.signature.username

要使用的签名密钥存储中的密钥的用户名或别名。如果未指定,它将使用属性文件中设置的默认别名。如果没有设置该密钥,并且密钥存储仅包含一个密钥,则将使用该密钥。

ws-security.encryption.username

要使用的加密密钥存储中的密钥的用户名或别名。如果未指定,它将使用属性文件中设置的默认别名。如果没有设置该密钥,并且密钥存储仅包含一个密钥,则将使用该密钥。对于 Web 服务提供商,useReqSigCert 关键字可用于接受(加密)任何公钥存在于服务的信任存储中的客户端(在 ws-security.encryption.properties 中定义)。

ws-security.signature.crypto

这可以指向完整的 WSS4J Crypto 对象,而不是指定签名属性。这样可以更轻松地对加密信息进行编程配置。

ws-security.encryption.crypto

这可以指向完整的 WSS4J Crypto 对象,而不是指定加密属性。这样可以更轻松地对加密信息进行编程配置。

ws-security.enable.streaming

启用 WS-Security 消息的流传输(基于 StAX)处理.

3.8.2. ws-Trust

WS-Trust 是一种 Web 服务规范,用于定义对 WS-Security 的扩展。它是在分布式系统中实施安全性的一般框架。该标准基于集中式安全令牌服务(STS),该服务能够验证客户端并发行包含各种身份验证和授权数据的令牌。该规范描述了用于安全性令牌规范、交换和验证的协议。以下规格在 WS-Trust 架构中扮演重要角色:

  • WS-SecurityPolicy 1.2
  • SAML 2.0
  • 用户名令牌配置集
  • X.509 令牌配置集
  • SAML 令牌配置集
  • Kerberos 令牌配置集

WS-Trust 扩展满足了跨越多个域且需要共享安全密钥的应用程序的需求。这可以通过提供基于标准的可信第三方 Web 服务(STS)来代理 Web 服务请求者和 Web 服务提供商之间的信任关系。此架构还通过提供此信息的常用位置,减轻了需要更改凭据的服务更新的难度。STS 是请求者和提供程序从中检索并验证安全令牌的常用访问点。

WS-Trust 规范有三个主要组件:

  • 用于发布、续订和验证安全令牌的安全令牌服务(STS)。
  • 安全令牌请求和响应的消息格式。
  • 密钥交换机制。

下面的部分解释了基本的 WS-Trust 场景。有关高级场景,请参阅 高级 WS-Trust 场景

3.8.2.1. 场景:基本 WS-Trust

在本节中,我们提供了一个基本的 WS-Trust 场景示例。它包含一个 Web 服务请求器(ws-requester)、Web 服务提供商(ws-provider)和安全令牌服务(STS)。

ws-provider 需要从指定的 STS 发布的 SAML 2.0 令牌由 ws-requester 使用非 对称绑定呈现。这些通信要求在 ws-provider 的 WSDL 中声明。STS 要求 ws-requester 凭据通过对称绑定在 WSS UsernameToken 格式请求中提供。提供来自 STS 的响应包含 SAML 2.0 令牌。这些通信要求在 STS 的 WSDL 中声明。

  1. ws-requester 联系 ws-provider 并使用其 WSDL。在找到安全令牌签发者要求时,ws-requester 会创建并配置 STSClient,使其包含生成有效请求所需的信息。
  2. STSClient 与 STS 联系并使用其 WSDL。发现安全策略。STSClient 创建并发送具有适当凭据的身份验证请求。
  3. STS 验证凭据。
  4. 作为响应,STS 签发了一个安全令牌,它提供 ws-requester 通过 STS 进行身份验证的证明。
  5. STSClient 向 ws-provider 呈现一条安全令牌消息。
  6. ws-provider 验证令牌是否由 STS 签发,因此证明 ws-requester 已通过 STS 成功验证了令牌。
  7. ws-provider 执行请求的服务,并将结果返回到 ws-requester

3.8.2.2. Apache CXF 支持

Apache CXF 是一个开源、功能全面的 Web 服务框架。JBossWS 开源项目将 JBoss Web Services(JBossWS)堆栈与 Apache CXF 项目模块集成,以提供 WS-Trust 和其他 Jakarta XML Web 服务功能。这种集成有助于轻松部署 Apache CXF STS 实施。Apache CXF API 还提供 STSClient 实用程序,以协助 Web 服务请求者与其 STS 通信。

3.8.3. 安全令牌服务(STS)

安全令牌服务(STS)是 WS-Trust 规范的核心。它是一种基于标准的验证和授权机制。STS 是基于令牌格式、命名空间或信任边界的 WS-Trust 规范协议用于发布、交换和验证安全令牌的一种实施。STS 是一个 Web 服务,充当可信第三方,以代理 Web 服务请求者和 Web 服务提供商之间的信任关系。它是请求者和提供商信任的常用接入点,可提供可互操作的安全令牌。它免除了请求者和供应商之间直接关系的需求。STS 有助于确保跨域和不同平台之间的互操作性,因为它是基于标准的身份验证机制。

STS 的 WSDL 合同定义了其他应用程序和进程如何与之交互。特别是,WSDL 定义了 WS-Trust 和 WS-Security 策略,请求者必须遵守这些策略才能与 STS 的端点成功通信。Web 服务请求者使用 STS 的 WSDL,并且在 STSClient 实用程序的帮助下,生成符合所声明安全策略的消息请求并将其提交到 STS 端点。STS 验证请求并返回适当的响应。

若要将客户端配置为从 STS 获取安全令牌,您需要使用 org.picketlink.identity.federation.api.wstrust.WSTrustClient 类以连接到 STS 并请求签发令牌。

首先,您需要实例化客户端:

示例:创建 WSTrustClient

 WSTrustClient client = new WSTrustClient("PicketLinkSTS", "PicketLinkSTSPort",
       "http://localhost:8080/SecureTokenService/PicketLinkSTS",
       new SecurityInfo(username, password));
Copy to Clipboard Toggle word wrap

接下来,您需要使用 WSTrustClient 来要求提供令牌,如 SAML 断言:

示例:包含 Assertion

org.w3c.dom.Element assertion = null;
try {
   assertion = client.issueToken(SAMLUtil.SAML2_TOKEN_TYPE);
} catch (WSTrustException wse) {
   System.out.println("Unable to issue assertion: " + wse.getMessage());
   wse.printStackTrace();
}
Copy to Clipboard Toggle word wrap

断言后,可以通过两种方式将它包含在 并通过 SOAP 消息发送:

  • 客户端可以将 SAML2 Assertion 推送到密钥 org.picketlink.trust.saml.assertion 下的 SOAP MessageContext 中。例如:

    bindingProvider.getRequestContext().put(SAML2Constants.SAML2_ASSERTION_PROPERTY, assertion);
    Copy to Clipboard Toggle word wrap
  • SAML2 Assertion 在安全上下文中作为 JAAS 主题的一部分提供。如果 JAAS 与 PicketLink STS 登录模块的使用进行了交互,则会出现此情况。

3.8.3.3. STS 客户端池

警告

JBoss EAP 不支持 STS 客户端池功能。

STS 客户端池是一种允许您在服务器上配置 STS 客户端池的功能,从而消除了 STS 客户端创建可能出现的瓶颈。客户端池可用于需要 STS 客户端来获取 SAML 票据的登录模块。包括:

  • org.picketlink.identity.federation.core.wstrust.auth.STSIssuingLoginModule
  • org.picketlink.identity.federation.core.wstrust.auth.STSValidatingLoginModule
  • org.picketlink.trust.jbossws.jaas.JBWSTokenIssuingLoginModule

每个登录模块的池中的默认客户端数量都使用 initialNumberOfClients 登录模块选项进行配置。

org.picketlink.identity.federation.bindings.stspool.STSClientPoolFactory 类为应用提供客户端池功能。

使用 STSClientPoolFactory

STS 客户端通过其 STSClientConfig 配置作为键插入到子池。要将 STS 客户端插入到子池中,您需要获取 STSClientPool 实例,然后根据配置初始化子池。(可选)您可以在初始化池时指定 STS 客户端的初始数量,或者您可以依赖默认编号。

示例:将 STS 客户端插入 Subpool

final STSClientPool pool = STSClientPoolFactory.getPoolInstance();
pool.createPool(20, stsClientConfig);
final STSClient client = pool.getClient(stsClientConfig);
Copy to Clipboard Toggle word wrap

使用完客户端后,您可以通过调用 returnClient() 方法将它返回到池。

示例:将 STS 客户端返回到 Subpool

pool.returnClient();
Copy to Clipboard Toggle word wrap

示例:检查是否使用给定配置检查子池是否存在

if (! pool.configExists(stsClientConfig) {
    pool.createPool(stsClientConfig);
}
Copy to Clipboard Toggle word wrap

如果启用了 picketlink-federation 子系统,则为部署创建的所有客户端池都会在取消部署过程中自动销毁。手动销毁池:

示例:手动销毁子池

pool.destroyPool(stsClientConfig);
Copy to Clipboard Toggle word wrap

webservices 子系统包含一个适配器,允许您配置 Elytron 安全域以使用注释或部署描述符保护 Web 服务端点的安全性。

启用 Elytron 安全性后,可将 JAAS 主题或主体推送到 Apache CXF 端点的 SecurityContext,将经过身份验证的身份传播到 Jakarta Enterprise Beans 容器。

以下是如何使用 Apache CXF 拦截器将验证信息传播到 Jakarta Enterprise Beans 容器的示例。

public class PropagateSecurityInterceptor extends WSS4JInInterceptor {
    public PropagateSecurityInterceptor() {
      super();
      getAfter().add(PolicyBasedWSS4JInInterceptor.class.getName());
   }
   @Override
   public void handleMessage(SoapMessage message) throws Fault {
      ...
      final Endpoint endpoint = message.getExchange().get(Endpoint.class);
      final SecurityDomainContext securityDomainContext = endpoint.getSecurityDomainContext();
      //push subject principal retrieved from CXF to ElytronSecurityDomainContext
      securityDomainContext.pushSubjectContext(subject, principal, null)
      }
    }
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat