A.8. 高级 WS-Trust 场景


A.8.1. 场景:SAML Holder-Of-Key Assertion 方案

WS-Trust 帮助管理软件安全令牌。SAML 断言是安全令牌的类型。在 Holder-Of-Key 方法中,STS 创建一个包含客户端公钥的 SAML 令牌,并使用其私钥为 SAML 令牌签名。客户端包括 SAML 令牌,并使用其私钥将传出的 soap 信封签名给 web 服务。Web 服务验证 SOAP 消息和 SAML 令牌。

实施此场景需要以下内容:

  • 必须保护带有 Holder-Of-Key 主题确认方法的 SAML 令牌,以便无法侦听令牌。在大多数情况下,Holder-Of-Key 令牌与 HTTPS 相结合足以防止获取令牌。这意味着安全策略使用 sp:TransportBindingsp:HttpsToken
  • Holder-Of-Key 令牌没有与其关联的加密或签名密钥,因此应该将 sp:IssuedToken of SymmetricKeyPublicKey keyType 用于 sp:SignedEndorsingSupportingTokens

A.8.1.1. Web 服务提供商

本节列出了 SAML Holder-Of-Key 场景的 Web 服务元素。这些组件包括:

A.8.1.1.1. Web 服务提供商 WSDL

Web 服务提供商是一个合同第一端点。HolderOfKeyService.wsdl WSDL 中声明的所有 WS-trust 和安全策略。在这种情况下,需要一个 ws-requester 来提供 SAML 2.0 令牌的 SymmetricKey keyType(由指定的 STS 发布)。STS 地址在 WSDL 中提供。使用传输绑定策略。该令牌被声明为签名和签名,SignedEndorsingSupportingTokens

以下列表中的注释中提供了安全设置的详细解释:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions targetNamespace="http://www.jboss.org/jbossws/ws-extensions/holderofkeywssecuritypolicy"
             name="HolderOfKeyService"
        xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/holderofkeywssecuritypolicy"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns="http://schemas.xmlsoap.org/wsdl/"
        xmlns:wsp="http://www.w3.org/ns/ws-policy"
        xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:wsaws="http://www.w3.org/2005/08/addressing"
    xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
    xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
    xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">

  <types>
    <xsd:schema>
      <xsd:import namespace="http://www.jboss.org/jbossws/ws-extensions/holderofkeywssecuritypolicy"
                  schemaLocation="HolderOfKeyService_schema1.xsd"/>
    </xsd:schema>
  </types>
  <message name="sayHello">
    <part name="parameters" element="tns:sayHello"/>
  </message>
  <message name="sayHelloResponse">
    <part name="parameters" element="tns:sayHelloResponse"/>
  </message>
  <portType name="HolderOfKeyIface">
    <operation name="sayHello">
      <input message="tns:sayHello"/>
      <output message="tns:sayHelloResponse"/>
    </operation>
  </portType>
<!--
        The wsp:PolicyReference binds the security requirements on all the endpoints.
        The wsp:Policy wsu:Id="#TransportSAML2HolderOfKeyPolicy" element is defined later in this file.
-->
  <binding name="HolderOfKeyServicePortBinding" type="tns:HolderOfKeyIface">
    <wsp:PolicyReference URI="#TransportSAML2HolderOfKeyPolicy" />
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="sayHello">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>
<!--
  The soap:address has been defined to use JBoss's https port, 8443.  This is
  set in conjunction with the sp:TransportBinding policy for https.
-->
  <service name="HolderOfKeyService">
    <port name="HolderOfKeyServicePort" binding="tns:HolderOfKeyServicePortBinding">
      <soap:address location="https://@jboss.bind.address@:8443/jaxws-samples-wsse-policy-trust-holderofkey/HolderOfKeyService"/>
    </port>
  </service>


  <wsp:Policy wsu:Id="TransportSAML2HolderOfKeyPolicy">
    <wsp:ExactlyOne>
      <wsp:All>
  <!--
        The wsam:Addressing element, indicates that the endpoints of this
        web service MUST conform to the WS-Addressing specification.  The
        attribute wsp:Optional="false" enforces this assertion.
  -->
        <wsam:Addressing wsp:Optional="false">
          <wsp:Policy />
        </wsam:Addressing>
<!--
  The sp:TransportBinding element indicates that security is provided by the
  message exchange transport medium, https.  WS-Security policy specification
  defines the sp:HttpsToken for use in exchanging messages transmitted over HTTPS.
-->
          <sp:TransportBinding
            xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
            <wsp:Policy>
              <sp:TransportToken>
                <wsp:Policy>
                  <sp:HttpsToken>
                    <wsp:Policy/>
                  </sp:HttpsToken>
                </wsp:Policy>
              </sp:TransportToken>
<!--
     The sp:AlgorithmSuite element, requires the TripleDes algorithm suite
     be used in performing cryptographic operations.
-->
              <sp:AlgorithmSuite>
                <wsp:Policy>
                  <sp:TripleDes />
                </wsp:Policy>
              </sp:AlgorithmSuite>
<!--
     The sp:Layout element,  indicates the layout rules to apply when adding
     items to the security header.  The sp:Lax sub-element indicates items
     are added to the security header in any order that conforms to
     WSS: SOAP Message Security.
-->
              <sp:Layout>
                <wsp:Policy>
                  <sp:Lax />
                </wsp:Policy>
              </sp:Layout>
              <sp:IncludeTimestamp />
            </wsp:Policy>
          </sp:TransportBinding>

<!--
  The sp:SignedEndorsingSupportingTokens, when transport level security level is
  used there will be no message signature and the signature generated by the
  supporting token will sign the Timestamp.
-->
        <sp:SignedEndorsingSupportingTokens
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
<!--
  The sp:IssuedToken element asserts that a SAML 2.0 security token of type
  Bearer is expected from the STS.  The
  sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
  attribute instructs the runtime to include the initiator's public key
  with every message sent to the recipient.

  The sp:RequestSecurityTokenTemplate element directs that all of the
  children of this element will be copied directly into the body of the
  RequestSecurityToken (RST) message that is sent to the STS when the
  initiator asks the STS to issue a token.
-->
            <sp:IssuedToken
              sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
              <sp:RequestSecurityTokenTemplate>
                <t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
 <!--
   KeyType of "SymmetricKey", the client must prove to the WS service that it
   possesses a particular symmetric session key.
 -->
                <t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</t:KeyType>
              </sp:RequestSecurityTokenTemplate>
              <wsp:Policy>
                <sp:RequireInternalReference />
              </wsp:Policy>
<!--
  The sp:Issuer element defines the STS's address and endpoint information
  This information is used by the STSClient.
-->
              <sp:Issuer>
                <wsaws:Address>http://@jboss.bind.address@:8080/jaxws-samples-wsse-policy-trust-sts-holderofkey/SecurityTokenService</wsaws:Address>
                <wsaws:Metadata
                  xmlns:wsdli="http://www.w3.org/2006/01/wsdl-instance"
                  wsdli:wsdlLocation="http://@jboss.bind.address@:8080/jaxws-samples-wsse-policy-trust-sts-holderofkey/SecurityTokenService?wsdl">
                  <wsaw:ServiceName
                    xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
                    xmlns:stsns="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
                    EndpointName="UT_Port">stsns:SecurityTokenService</wsaw:ServiceName>
                </wsaws:Metadata>
              </sp:Issuer>

            </sp:IssuedToken>
          </wsp:Policy>
        </sp:SignedEndorsingSupportingTokens>
<!--
    The sp:Wss11 element declares WSS: SOAP Message Security 1.1 options
    to be supported by the STS.  These particular elements generally refer
    to how keys are referenced within the SOAP envelope.  These are normally handled by Apache CXF.
-->
        <sp:Wss11>
          <wsp:Policy>
            <sp:MustSupportRefIssuerSerial />
            <sp:MustSupportRefThumbprint />
            <sp:MustSupportRefEncryptedKey />
          </wsp:Policy>
        </sp:Wss11>
<!--
    The sp:Trust13 element declares controls for WS-Trust 1.3 options.
    They are policy assertions related to exchanges specifically with
    client and server challenges and entropy behaviors.  Again these are
    normally handled by Apache CXF.
-->
        <sp:Trust13>
          <wsp:Policy>
            <sp:MustSupportIssuedTokens />
            <sp:RequireClientEntropy />
            <sp:RequireServerEntropy />
          </wsp:Policy>
        </sp:Trust13>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

</definitions>
Copy to Clipboard Toggle word wrap
A.8.1.1.2. SSL 配置

此 Web 服务使用 HTTPS,因此必须将 JBoss EAP 服务器配置为在 undertow 子系统中提供 SSL/TLS 支持。

有关如何为 Web 应用程序配置 HTTPS 的详情,请参考如何配置 服务器安全性为应用程序配置单向和双向 SSL/TLS

A.8.1.1.3. Web 服务提供商接口

Web 服务提供商接口 HolderOfKeyIface 类是一个简单的 Web 服务定义。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.holderofkey;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
(
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/holderofkeywssecuritypolicy"
)
public interface HolderOfKeyIface {
   @WebMethod
   String sayHello();
}
Copy to Clipboard Toggle word wrap
A.8.1.1.4. Web 服务提供商实施

Web 服务提供商实施 HolderOfKeyImpl 类是一个简单的 POJO。它使用标准的 WebService 注释来定义服务端点。此外,还有两个 Apache CXF 注解,Ed pointPropertiesEndpointProperty 用于为 Apache CXF 运行时配置端点。这些注释来自 Apache WSS4J 项目,该项目为 Web 服务提供了主 WS-Security 标准的 Java 实施。这些注释以编程方式向端点添加属性。使用普通 Apache CXF 时,这些属性通常使用 Spring 配置中的 <jaxws:properties&gt; 元素进行设置。这些注释允许在代码中配置属性。

WSS4J 使用 Crypto 接口获取用于签名创建/验证的密钥和证书,如 WSDL 为此服务的要求。HolderOfKeyImpl 提供的 WSS4J 配置信息用于 Crypto 的 Merlin 实施。

列表中的第一个 EndpointProperty 语句禁用了对基本安全配置文件 1.1 的合规性。下一个 EndpointProperty 语句声明包含(Merlin)Crypto 配置信息的 Java 属性文件。最后的 EndpointProperty 语句声明 STSHolderOfKeyCallbackHandler 实施类。它用于获取密钥存储文件中证书的密码。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.holderofkey;

import org.apache.cxf.annotations.EndpointProperties;
import org.apache.cxf.annotations.EndpointProperty;

import javax.jws.WebService;

@WebService
   (
      portName = "HolderOfKeyServicePort",
      serviceName = "HolderOfKeyService",
      wsdlLocation = "WEB-INF/wsdl/HolderOfKeyService.wsdl",
      targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/holderofkeywssecuritypolicy",
      endpointInterface = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.holderofkey.HolderOfKeyIface"
   )
@EndpointProperties(value = {
   @EndpointProperty(key = "ws-security.is-bsp-compliant", value = "false"),
   @EndpointProperty(key = "ws-security.signature.properties", value = "serviceKeystore.properties"),
   @EndpointProperty(key = "ws-security.callback-handler", value = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.holderofkey.HolderOfKeyCallbackHandler")
})
public class HolderOfKeyImpl implements HolderOfKeyIface {
   public String sayHello() {
      return "Holder-Of-Key WS-Trust Hello World!";
   }
}
Copy to Clipboard Toggle word wrap
A.8.1.1.5. 加密属性和密钥存储文件

WSS4J 的 Crypto 实施通过包含 Crypto 配置数据的 Java 属性文件来加载和配置。文件包含特定于实施的属性,如密钥存储位置、密码、默认别名等。这个应用程序使用 Merlin 实施。serviceKeystore.properties 文件包含此信息。

servicestore.jks 文件是 Java KeyStore(JKS)存储库。它包含 myservicekey 和 mystskey 的自签名证书。

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=sspass
org.apache.ws.security.crypto.merlin.keystore.alias=myservicekey
org.apache.ws.security.crypto.merlin.keystore.file=servicestore.jks
Copy to Clipboard Toggle word wrap
A.8.1.1.6. 默认 MANIFEST.MF

此应用程序需要访问 org.jboss.ws.cxf.jbossws-cxf 中提供的 JBossWS 和 Apache CXF API。dependency 语句指示服务器在部署时提供它们。

Manifest-Version: 1.0
Dependencies: org.jboss.ws.cxf.jbossws-cxf-client
Copy to Clipboard Toggle word wrap

A.8.2. 场景:SAML Bearerions

WS-Trust 管理软件安全令牌。SAML 断言是安全令牌的类型。在 SAML Bearer 场景中,服务提供商会在服务验证令牌签名后自动信任传入的 SOAP 请求来自 SAML 令牌中定义的主题。

实施此方案需要满足以下要求:

  • 带有 Bearer 主题确认方法的 SAML 令牌必须受到保护,以便令牌不能被嗅探。在大多数情况下,bearer 令牌与 HTTPS 相结合足以防止"中间人"获得令牌。这意味着使用 sp: TransportBinding 和 sp: HttpsToken 的安全策略。
  • bearer 令牌没有与之关联的加密或签名密钥,因此 bearer keyType 的 sp:IssuedToken 应当用于 sp:SupportingToken 或 sp:SignedSupportingTokens

A.8.2.1. Web 服务提供商

本节探讨 SAML Bearer 场景的 Web 服务元素。这些组件包括:

A.8.2.1.1. bearer Web Service Provider WSDL

Web 服务提供商是一个合同第一端点。WS-信任和安全策略在 BearerService.wsdl WSDL 中声明。在这种情况下,Wer-requester 需要提供由指定的 STS 发布的 SAML 2.0 Bearer 令牌。STS 的地址在 WSDL 中提供。HTTPS、传输绑定和 HttpsToken 策略用于保护在 ws-requester 和 ws- provider 之间发送的消息的 SOAP 正文。安全设置详细信息在以下列表中作为注释提供:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions targetNamespace="http://www.jboss.org/jbossws/ws-extensions/bearerwssecuritypolicy"
             name="BearerService"
             xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/bearerwssecuritypolicy"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:wsp="http://www.w3.org/ns/ws-policy"
             xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
             xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
             xmlns:wsaws="http://www.w3.org/2005/08/addressing"
             xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
             xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
             xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">

  <types>
    <xsd:schema>
      <xsd:import namespace="http://www.jboss.org/jbossws/ws-extensions/bearerwssecuritypolicy"
                  schemaLocation="BearerService_schema1.xsd"/>
    </xsd:schema>
  </types>
  <message name="sayHello">
    <part name="parameters" element="tns:sayHello"/>
  </message>
  <message name="sayHelloResponse">
    <part name="parameters" element="tns:sayHelloResponse"/>
  </message>
  <portType name="BearerIface">
    <operation name="sayHello">
      <input message="tns:sayHello"/>
      <output message="tns:sayHelloResponse"/>
    </operation>
  </portType>

<!--
        The wsp:PolicyReference binds the security requirments on all the endpoints.
        The wsp:Policy wsu:Id="#TransportSAML2BearerPolicy" element is defined later in this file.
-->
  <binding name="BearerServicePortBinding" type="tns:BearerIface">
    <wsp:PolicyReference URI="#TransportSAML2BearerPolicy" />
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="sayHello">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>

<!--
  The soap:address has been defined to use JBoss's https port, 8443.  This is
  set in conjunction with the sp:TransportBinding policy for https.
-->
  <service name="BearerService">
    <port name="BearerServicePort" binding="tns:BearerServicePortBinding">
      <soap:address location="https://@jboss.bind.address@:8443/jaxws-samples-wsse-policy-trust-bearer/BearerService"/>
    </port>
  </service>


  <wsp:Policy wsu:Id="TransportSAML2BearerPolicy">
    <wsp:ExactlyOne>
      <wsp:All>
  <!--
        The wsam:Addressing element, indicates that the endpoints of this
        web service MUST conform to the WS-Addressing specification.  The
        attribute wsp:Optional="false" enforces this assertion.
  -->
        <wsam:Addressing wsp:Optional="false">
          <wsp:Policy />
        </wsam:Addressing>

<!--
  The sp:TransportBinding element indicates that security is provided by the
  message exchange transport medium, https.  WS-Security policy specification
  defines the sp:HttpsToken for use in exchanging messages transmitted over HTTPS.
-->
        <sp:TransportBinding
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:TransportToken>
              <wsp:Policy>
                <sp:HttpsToken>
                  <wsp:Policy/>
                </sp:HttpsToken>
              </wsp:Policy>
            </sp:TransportToken>
<!--
     The sp:AlgorithmSuite element, requires the TripleDes algorithm suite
     be used in performing cryptographic operations.
-->
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:TripleDes />
              </wsp:Policy>
            </sp:AlgorithmSuite>
<!--
     The sp:Layout element,  indicates the layout rules to apply when adding
     items to the security header.  The sp:Lax sub-element indicates items
     are added to the security header in any order that conforms to
     WSS: SOAP Message Security.
-->
            <sp:Layout>
              <wsp:Policy>
                <sp:Lax />
              </wsp:Policy>
            </sp:Layout>
            <sp:IncludeTimestamp />
          </wsp:Policy>
        </sp:TransportBinding>

<!--
  The sp:SignedSupportingTokens element causes the supporting tokens
  to be signed using the primary token that is used to sign the message.
-->
        <sp:SignedSupportingTokens
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
<!--
  The sp:IssuedToken element asserts that a SAML 2.0 security token of type
  Bearer is expected from the STS.  The
  sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
  attribute instructs the runtime to include the initiator's public key
  with every message sent to the recipient.

  The sp:RequestSecurityTokenTemplate element directs that all of the
  children of this element will be copied directly into the body of the
  RequestSecurityToken (RST) message that is sent to the STS when the
  initiator asks the STS to issue a token.
-->
            <sp:IssuedToken
              sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
              <sp:RequestSecurityTokenTemplate>
                <t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
                <t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</t:KeyType>
              </sp:RequestSecurityTokenTemplate>
              <wsp:Policy>
                <sp:RequireInternalReference />
              </wsp:Policy>
<!--
  The sp:Issuer element defines the STS's address and endpoint information
  This information is used by the STSClient.
-->
              <sp:Issuer>
                <wsaws:Address>http://@jboss.bind.address@:8080/jaxws-samples-wsse-policy-trust-sts-bearer/SecurityTokenService</wsaws:Address>
                <wsaws:Metadata
                  xmlns:wsdli="http://www.w3.org/2006/01/wsdl-instance"
                  wsdli:wsdlLocation="http://@jboss.bind.address@:8080/jaxws-samples-wsse-policy-trust-sts-bearer/SecurityTokenService?wsdl">
                  <wsaw:ServiceName
                    xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
                    xmlns:stsns="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
                    EndpointName="UT_Port">stsns:SecurityTokenService</wsaw:ServiceName>
                </wsaws:Metadata>
              </sp:Issuer>

            </sp:IssuedToken>
          </wsp:Policy>
        </sp:SignedSupportingTokens>
<!--
    The sp:Wss11 element declares WSS: SOAP Message Security 1.1 options
    to be supported by the STS.  These particular elements generally refer
    to how keys are referenced within the SOAP envelope.  These are normally handled by Apache CXF.
-->
        <sp:Wss11>
          <wsp:Policy>
            <sp:MustSupportRefIssuerSerial />
            <sp:MustSupportRefThumbprint />
            <sp:MustSupportRefEncryptedKey />
          </wsp:Policy>
        </sp:Wss11>
<!--
    The sp:Trust13 element declares controls for WS-Trust 1.3 options.
    They are policy assertions related to exchanges specifically with
    client and server challenges and entropy behaviors.  Again these are
    normally handled by Apache CXF.
-->
        <sp:Trust13>
          <wsp:Policy>
            <sp:MustSupportIssuedTokens />
            <sp:RequireClientEntropy />
            <sp:RequireServerEntropy />
          </wsp:Policy>
        </sp:Trust13>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

</definitions>
Copy to Clipboard Toggle word wrap
A.8.2.1.2. SSL 配置

此 Web 服务使用 HTTPS,因此必须将 JBoss EAP 服务器配置为在 undertow 子系统中提供 SSL 支持。

有关如何为 Web 应用程序配置 HTTPS 的详情,请参考如何配置 服务器安全性为应用程序配置单向和双向 SSL/TLS

A.8.2.1.3. bearer Web 服务提供商接口

BearerIface Bearer Web 服务提供商接口类是一个简单的 Web 服务定义。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.bearer;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
(
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/bearerwssecuritypolicy"
)
public interface BearerIface {
   @WebMethod
   String sayHello();
}
Copy to Clipboard Toggle word wrap
A.8.2.1.4. bearer Web Service Providers 实施

BearerImpl Web 服务提供商实施类是一个简单的 POJO。它使用标准的 WebService 注释来定义服务端点。此外,还有两个 Apache CXF 注解,Ed pointPropertiesEndpointProperty 用于为 Apache CXF 运行时配置端点。这些注释来自 Apache WSS4J 项目,该项目为 Web 服务提供了主 WS-Security 标准的 Java 实施。这些注释以编程方式向端点添加属性。使用普通 Apache CXF 时,这些属性通常使用 Spring 配置中的 <jaxws:properties&gt; 元素进行设置。这些注释允许在代码中配置属性。

WSS4J 使用 Crypto 接口获取用于签名创建/验证的密钥和证书,如 WSDL 为此服务的要求。BearerImpl 提供的 WSS4J 配置信息用于 Crypto 的 Merlin 实施。

由于 Web 服务提供商自动信任来自 SAML 令牌中定义的主题的传入 SOAP 请求,所以与前面的示例中不同,Crypto CallbackHandler 类或签名用户名不需要该请求。但是,为了验证消息签名,仍然需要包含(Merlin)Crypto 配置信息的 Java 属性文件。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.bearer;

import org.apache.cxf.annotations.EndpointProperties;
import org.apache.cxf.annotations.EndpointProperty;

import javax.jws.WebService;

@WebService
(
   portName = "BearerServicePort",
   serviceName = "BearerService",
   wsdlLocation = "WEB-INF/wsdl/BearerService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/bearerwssecuritypolicy",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.bearer.BearerIface"
)
@EndpointProperties(value = {
   @EndpointProperty(key = "ws-security.signature.properties", value = "serviceKeystore.properties")
})
public class BearerImpl implements BearerIface {
   public String sayHello() {
      return "Bearer WS-Trust Hello World!";
   }
}
Copy to Clipboard Toggle word wrap
A.8.2.1.5. 加密属性和密钥存储文件

WSS4J 的 Crypto 实施通过包含 Crypto 配置数据的 Java 属性文件来加载和配置。文件包含特定于实施的属性,如密钥存储位置、密码、默认别名等。此应用程序正在使用 Merlin 实施。serviceKeystore.properties 文件包含此信息。

servicestore.jks 文件是 Java KeyStore(JKS)存储库。它包含 myservicekey 和 mystskey 的自签名证书。

注意

自签名证书不适合在生产环境中使用。

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=sspass
org.apache.ws.security.crypto.merlin.keystore.alias=myservicekey
org.apache.ws.security.crypto.merlin.keystore.file=servicestore.jks
Copy to Clipboard Toggle word wrap
A.8.2.1.6. 默认 MANIFEST.MF

部署时,此应用程序需要访问模块 org.jboss.ws.cxf.jbossws-cxf.jbossws-cxf-client 提供的 JBossWS 和 Apache CXF API。dependency 语句指示服务器在部署时提供它们。

Manifest-Version: 1.0
Dependencies: org.jboss.ws.cxf.jbossws-cxf-client
Copy to Clipboard Toggle word wrap

A.8.2.2. bearer 安全令牌服务

本节列出了提供 SAML Bearer 令牌提供安全令牌服务功能的关键元素。这些组件包括:

A.8.2.2.1. 安全域

STS 需要配置 JBoss 安全域。jboss-web.xml 描述符声明了已命名的安全域JBossWS-trust-st, 供此服务用于身份验证。此安全域需要两个属性文件,并在 JBoss EAP 服务器配置文件中添加安全域声明。

在这种情况下,域需要包含用户 alice、密码 clarinet 和角色 朋友。请参考以下关于 jbossws-users.propertiesjbossws-roles.properties 的列表 :此外,必须将以下 XML 添加到服务器配置文件中的 JBoss security 子系统中:

注意

将"SOME_PATH"替换为适当的信息。

<security-domain name="JBossWS-trust-sts">
  <authentication>
    <login-module code="UsersRoles" flag="required">
      <module-option name="usersProperties" value="/SOME_PATH/jbossws-users.properties"/>
      <module-option name="unauthenticatedIdentity" value="anonymous"/>
      <module-option name="rolesProperties" value="/SOME_PATH/jbossws-roles.properties"/>
    </login-module>
  </authentication>
</security-domain>
Copy to Clipboard Toggle word wrap

示例: jboss-web.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.4//EN" ">
<jboss-web>
  <security-domain>java:/jaas/JBossWS-trust-sts</security-domain>
</jboss-web>
Copy to Clipboard Toggle word wrap

示例: jbossws-users.properties 文件

# A sample users.properties file for use with the UsersRolesLoginModule
alice=clarinet
Copy to Clipboard Toggle word wrap

示例: jbossws-roles.properties 文件

# A sample roles.properties file for use with the UsersRolesLoginModule
alice=friend
Copy to Clipboard Toggle word wrap

A.8.2.2.2. STS WSDL
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
  targetNamespace="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
  xmlns:tns="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
  xmlns:wstrust="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:wsap10="http://www.w3.org/2006/05/addressing/wsdl"
  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
  xmlns:wsp="http://www.w3.org/ns/ws-policy"
  xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata">

  <wsdl:types>
    <xs:schema elementFormDefault="qualified"
               targetNamespace='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>

      <xs:element name='RequestSecurityToken'
                  type='wst:AbstractRequestSecurityTokenType'/>
      <xs:element name='RequestSecurityTokenResponse'
                  type='wst:AbstractRequestSecurityTokenType'/>

      <xs:complexType name='AbstractRequestSecurityTokenType'>
        <xs:sequence>
          <xs:any namespace='##any' processContents='lax' minOccurs='0'
                  maxOccurs='unbounded'/>
        </xs:sequence>
        <xs:attribute name='Context' type='xs:anyURI' use='optional'/>
        <xs:anyAttribute namespace='##other' processContents='lax'/>
      </xs:complexType>
      <xs:element name='RequestSecurityTokenCollection'
                  type='wst:RequestSecurityTokenCollectionType'/>
      <xs:complexType name='RequestSecurityTokenCollectionType'>
        <xs:sequence>
          <xs:element name='RequestSecurityToken'
                      type='wst:AbstractRequestSecurityTokenType' minOccurs='2'
                      maxOccurs='unbounded'/>
        </xs:sequence>
      </xs:complexType>

      <xs:element name='RequestSecurityTokenResponseCollection'
                  type='wst:RequestSecurityTokenResponseCollectionType'/>
      <xs:complexType name='RequestSecurityTokenResponseCollectionType'>
        <xs:sequence>
          <xs:element ref='wst:RequestSecurityTokenResponse' minOccurs='1'
                      maxOccurs='unbounded'/>
        </xs:sequence>
        <xs:anyAttribute namespace='##other' processContents='lax'/>
      </xs:complexType>

    </xs:schema>
  </wsdl:types>

  <!-- WS-Trust defines the following GEDs -->
  <wsdl:message name="RequestSecurityTokenMsg">
    <wsdl:part name="request" element="wst:RequestSecurityToken"/>
  </wsdl:message>
  <wsdl:message name="RequestSecurityTokenResponseMsg">
    <wsdl:part name="response"
               element="wst:RequestSecurityTokenResponse"/>
  </wsdl:message>
  <wsdl:message name="RequestSecurityTokenCollectionMsg">
    <wsdl:part name="requestCollection"
               element="wst:RequestSecurityTokenCollection"/>
  </wsdl:message>
  <wsdl:message name="RequestSecurityTokenResponseCollectionMsg">
    <wsdl:part name="responseCollection"
               element="wst:RequestSecurityTokenResponseCollection"/>
  </wsdl:message>

  <!-- This portType an example of a Requestor (or other) endpoint that
  Accepts SOAP-based challenges from a Security Token Service -->
  <wsdl:portType name="WSSecurityRequestor">
    <wsdl:operation name="Challenge">
      <wsdl:input message="tns:RequestSecurityTokenResponseMsg"/>
      <wsdl:output message="tns:RequestSecurityTokenResponseMsg"/>
    </wsdl:operation>
  </wsdl:portType>

  <!-- This portType is an example of an STS supporting full protocol -->
  <!--
      The wsdl:portType and data types are XML elements defined by the
      WS_Trust specification.  The wsdl:portType defines the endpoints
      supported in the STS implementation.  This WSDL defines all operations
      that an STS implementation can support.
  -->
  <wsdl:portType name="STS">
    <wsdl:operation name="Cancel">
      <wsdl:input
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Cancel"
        message="tns:RequestSecurityTokenMsg"/>
      <wsdl:output
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/CancelFinal"
        message="tns:RequestSecurityTokenResponseMsg"/>
    </wsdl:operation>
    <wsdl:operation name="Issue">
      <wsdl:input
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue"
        message="tns:RequestSecurityTokenMsg"/>
      <wsdl:output
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal"
        message="tns:RequestSecurityTokenResponseCollectionMsg"/>
    </wsdl:operation>
    <wsdl:operation name="Renew">
      <wsdl:input
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Renew"
        message="tns:RequestSecurityTokenMsg"/>
      <wsdl:output
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/RenewFinal"
        message="tns:RequestSecurityTokenResponseMsg"/>
    </wsdl:operation>
    <wsdl:operation name="Validate">
      <wsdl:input
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Validate"
        message="tns:RequestSecurityTokenMsg"/>
      <wsdl:output
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/ValidateFinal"
        message="tns:RequestSecurityTokenResponseMsg"/>
    </wsdl:operation>
    <wsdl:operation name="KeyExchangeToken">
      <wsdl:input
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/KET"
        message="tns:RequestSecurityTokenMsg"/>
      <wsdl:output
        wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/KETFinal"
        message="tns:RequestSecurityTokenResponseMsg"/>
    </wsdl:operation>
    <wsdl:operation name="RequestCollection">
      <wsdl:input message="tns:RequestSecurityTokenCollectionMsg"/>
      <wsdl:output message="tns:RequestSecurityTokenResponseCollectionMsg"/>
    </wsdl:operation>
  </wsdl:portType>

  <!-- This portType is an example of an endpoint that accepts
  Unsolicited RequestSecurityTokenResponse messages -->
  <wsdl:portType name="SecurityTokenResponseService">
    <wsdl:operation name="RequestSecurityTokenResponse">
      <wsdl:input message="tns:RequestSecurityTokenResponseMsg"/>
    </wsdl:operation>
  </wsdl:portType>

  <!--
      The wsp:PolicyReference binds the security requirments on all the STS endpoints.
      The wsp:Policy wsu:Id="UT_policy" element is later in this file.
  -->
  <wsdl:binding name="UT_Binding" type="wstrust:STS">
    <wsp:PolicyReference URI="#UT_policy"/>
    <soap:binding style="document"
                  transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="Issue">
      <soap:operation
        soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue"/>
      <wsdl:input>
        <wsp:PolicyReference
          URI="#Input_policy"/>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <wsp:PolicyReference
          URI="#Output_policy"/>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="Validate">
      <soap:operation
        soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Validate"/>
      <wsdl:input>
        <wsp:PolicyReference
          URI="#Input_policy"/>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <wsp:PolicyReference
          URI="#Output_policy"/>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="Cancel">
      <soap:operation
        soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Cancel"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="Renew">
      <soap:operation
        soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Renew"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="KeyExchangeToken">
      <soap:operation
        soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/KeyExchangeToken"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="RequestCollection">
      <soap:operation
        soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/RequestCollection"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>

  <wsdl:service name="SecurityTokenService">
    <wsdl:port name="UT_Port" binding="tns:UT_Binding">
      <soap:address location="http://localhost:8080/SecurityTokenService/UT"/>
    </wsdl:port>
  </wsdl:service>


  <wsp:Policy wsu:Id="UT_policy">
    <wsp:ExactlyOne>
      <wsp:All>
        <!--
            The sp:UsingAddressing element, indicates that the endpoints of this
            web service conforms to the WS-Addressing specification.  More detail
            can be found here: [http://www.w3.org/TR/2006/CR-ws-addr-wsdl-20060529]
        -->
        <wsap10:UsingAddressing/>
        <!--
            The sp:SymmetricBinding element indicates that security is provided
            at the SOAP layer and any initiator must authenticate itself by providing
            WSS UsernameToken credentials.
        -->
        <sp:SymmetricBinding
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <!--
                In a symmetric binding, the keys used for encrypting and signing in both
                directions are derived from a single key, the one specified by the
                sp:ProtectionToken element.  The sp:X509Token sub-element declares this
                key to be a X.509 certificate and the
                IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never"
                attribute adds the requirement that the token MUST NOT be included in
                any messages sent between the initiator and the recipient; rather, an
                external reference to the token should be used.  Lastly the WssX509V3Token10
                sub-element declares that the Username token presented by the initiator
                should be compliant with Web Services Security UsernameToken Profile
                1.0 specification. [ http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf ]
            -->
            <sp:ProtectionToken>
              <wsp:Policy>
                <sp:X509Token
                  sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
                  <wsp:Policy>
                    <sp:RequireDerivedKeys/>
                    <sp:RequireThumbprintReference/>
                    <sp:WssX509V3Token10/>
                  </wsp:Policy>
                </sp:X509Token>
              </wsp:Policy>
            </sp:ProtectionToken>
            <!--
                The sp:AlgorithmSuite element, requires the Basic256 algorithm suite
                be used in performing cryptographic operations.
            -->
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:Basic256/>
              </wsp:Policy>
            </sp:AlgorithmSuite>
            <!--
                The sp:Layout element,  indicates the layout rules to apply when adding
                items to the security header.  The sp:Lax sub-element indicates items
                are added to the security header in any order that conforms to
                WSS: SOAP Message Security.
            -->
            <sp:Layout>
              <wsp:Policy>
                <sp:Lax/>
              </wsp:Policy>
            </sp:Layout>
            <sp:IncludeTimestamp/>
            <sp:EncryptSignature/>
            <sp:OnlySignEntireHeadersAndBody/>
          </wsp:Policy>
        </sp:SymmetricBinding>

        <!--
            The sp:SignedSupportingTokens element declares that the security header
            of messages must contain a sp:UsernameToken and the token must be signed.
            The attribute IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"
            on sp:UsernameToken indicates that the token MUST be included in all
            messages sent from initiator to the recipient and that the token MUST
            NOT be included in messages sent from the recipient to the initiator.
            And finally the element sp:WssUsernameToken10 is a policy assertion
            indicating the Username token should be as defined in  Web Services
            Security UsernameToken Profile 1.0
        -->
        <sp:SignedSupportingTokens
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:UsernameToken
              sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
              <wsp:Policy>
                <sp:WssUsernameToken10/>
              </wsp:Policy>
            </sp:UsernameToken>
          </wsp:Policy>
        </sp:SignedSupportingTokens>
        <!--
            The sp:Wss11 element declares WSS: SOAP Message Security 1.1 options
            to be supported by the STS.  These particular elements generally refer
            to how keys are referenced within the SOAP envelope.  These are normally
            handled by Apache CXF.
        -->
        <sp:Wss11
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:MustSupportRefKeyIdentifier/>
            <sp:MustSupportRefIssuerSerial/>
            <sp:MustSupportRefThumbprint/>
            <sp:MustSupportRefEncryptedKey/>
          </wsp:Policy>
        </sp:Wss11>
        <!--
            The sp:Trust13 element declares controls for WS-Trust 1.3 options.
            They are policy assertions related to exchanges specifically with
            client and server challenges and entropy behaviors.  Again these are
            normally handled by Apache CXF.
        -->
        <sp:Trust13
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:MustSupportIssuedTokens/>
            <sp:RequireClientEntropy/>
            <sp:RequireServerEntropy/>
          </wsp:Policy>
        </sp:Trust13>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

  <wsp:Policy wsu:Id="Input_policy">
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:SignedParts
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <sp:Body/>
          <sp:Header Name="To"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="From"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="FaultTo"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="ReplyTo"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="MessageID"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="RelatesTo"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="Action"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
        </sp:SignedParts>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

  <wsp:Policy wsu:Id="Output_policy">
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:SignedParts
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <sp:Body/>
          <sp:Header Name="To"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="From"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="FaultTo"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="ReplyTo"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="MessageID"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="RelatesTo"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
          <sp:Header Name="Action"
                     Namespace="http://www.w3.org/2005/08/addressing"/>
        </sp:SignedParts>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

</wsdl:definitions>
Copy to Clipboard Toggle word wrap
A.8.2.2.3. STS 实施类

Apache CXF 的 STS SecurityTokenServiceProvider 是符合 WS-Trust 规范中定义的协议和功能的 Web 服务提供商。它具有模块化架构,其组件可配置或可替换。实施和配置插件可以启用可选功能。您可以通过从 SecurityTokenServiceProvider 扩展并覆盖默认设置来自定义自己的 STS。

SampleSTSBearer STS 实施类是从 SecurityTokenServiceProvider 扩展的 POJO。

注意

SampleSTSBearer 类使用 WebServiceProvider 注释来定义,而不是使用 WebService 注释。此注释将服务定义为基于 提供程序的端点,它支持面向消息传递的 Web 服务方法。特别是,它表示交换的消息将是 XML 文档。SecurityTokenServiceProviderjavax.xml.ws.Provider 接口的一种实施。相比之下,WebService 注释定义基于服务端点接口的端点,该端点支持使用 SOAP 信封进行消息交换。

BearerImpl 类中所做的操作,WSS4J 注解 EndpointPropertiesEndpointProperty 为 Apache CXF 运行时提供端点配置。列表中的第一个 EndpointProperty 语句声明了用于消息签名的用户名称。它在密钥存储中用作别名名称,用于获取用户签名的证书和私钥。接下来的两个 EndpointProperty 语句声明包含(Merlin)Crypto 配置信息的 Java 属性文件。在本例中,用于签名和加密消息。WSS4J 读取此文件,以及消息处理所需的信息。最后的 EndpointProperty 语句声明 STSBearerCallbackHandler 实施类。它用于获取密钥存储文件中证书的密码。

在这种实施中,我们自定义令牌规范、令牌验证及其静态属性的操作。

StaticSTSProperties 用于设置用于在 STS 中配置资源的选项。这看起来像是使用 WSS4J 注释进行的设置重复。值相同,但设置的下层结构不同,因此必须在两个位置声明此信息。

setIssuer 设置很重要,因为它唯一地标识了发行的 STS。签发者字符串嵌入了发布的令牌中,在验证令牌时,STS 会检查签发者字符串值。因此,务必要以一致的方式使用签发者字符串,以便 STS 可以识别发布的令牌。

setEndpoints 调用允许按地址声明一组允许的令牌接收者。地址指定为 reg-ex 模式。

TokenIssueOperation 具有一个模块化结构。这允许将自定义行为注入到消息处理中。在本例中,我们将覆盖 SecurityTokenServiceProvider 默认行为并执行 SAML 令牌处理。Apache CXF 提供了 SAMLTokenProvider 的一种实施,它可用于而不是创建 SAMLTokenProvider。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.stsbearer;

import org.apache.cxf.annotations.EndpointProperties;
import org.apache.cxf.annotations.EndpointProperty;
import org.apache.cxf.sts.StaticSTSProperties;
import org.apache.cxf.sts.operation.TokenIssueOperation;
import org.apache.cxf.sts.service.ServiceMBean;
import org.apache.cxf.sts.service.StaticService;
import org.apache.cxf.sts.token.provider.SAMLTokenProvider;
import org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider;

import javax.xml.ws.WebServiceProvider;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

@WebServiceProvider(serviceName = "SecurityTokenService",
      portName = "UT_Port",
      targetNamespace = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/",
      wsdlLocation = "WEB-INF/wsdl/bearer-ws-trust-1.4-service.wsdl")
//dependency on org.apache.cxf module or on module that exports org.apache.cxf (e.g. org.jboss.ws.cxf.jbossws-cxf-client) is needed, otherwise Apache CXF annotations are ignored
@EndpointProperties(value = {
      @EndpointProperty(key = "ws-security.signature.username", value = "mystskey"),
      @EndpointProperty(key = "ws-security.signature.properties", value = "stsKeystore.properties"),
      @EndpointProperty(key = "ws-security.callback-handler", value = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.stsbearer.STSBearerCallbackHandler")
})
public class SampleSTSBearer extends SecurityTokenServiceProvider {

   public SampleSTSBearer() throws Exception {
      super();

      StaticSTSProperties props = new StaticSTSProperties();
      props.setSignatureCryptoProperties("stsKeystore.properties");
      props.setSignatureUsername("mystskey");
      props.setCallbackHandlerClass(STSBearerCallbackHandler.class.getName());
      props.setEncryptionCryptoProperties("stsKeystore.properties");
      props.setEncryptionUsername("myservicekey");
      props.setIssuer("DoubleItSTSIssuer");

      List<ServiceMBean> services = new LinkedList<ServiceMBean>();
      StaticService service = new StaticService();
      service.setEndpoints(Arrays.asList(
         "https://localhost:(\\d)*/jaxws-samples-wsse-policy-trust-bearer/BearerService",
         "https://\\[::1\\]:(\\d)*/jaxws-samples-wsse-policy-trust-bearer/BearerService",
         "https://\\[0:0:0:0:0:0:0:1\\]:(\\d)*/jaxws-samples-wsse-policy-trust-bearer/BearerService"
      ));
      services.add(service);

      TokenIssueOperation issueOperation = new TokenIssueOperation();
      issueOperation.getTokenProviders().add(new SAMLTokenProvider());
      issueOperation.setServices(services);
      issueOperation.setStsProperties(props);
      this.setIssueOperation(issueOperation);
   }
}
Copy to Clipboard Toggle word wrap
A.8.2.2.4. STSBearerCallbackHandler Class

STSBearerCallbackHandler 是 WSS4J Crypto API 的回调处理程序。它用于在密钥存储中获取私钥的密码。此类使 Apache CXF 能够检索用于消息签名的用户名密码。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.stsbearer;

import org.jboss.wsf.stack.cxf.extensions.security.PasswordCallbackHandler;

import java.util.HashMap;
import java.util.Map;

public class STSBearerCallbackHandler extends PasswordCallbackHandler {
   public STSBearerCallbackHandler() {
      super(getInitMap());
   }

   private static Map<String, String> getInitMap() {
      Map<String, String> passwords = new HashMap<String, String>();
      passwords.put("mystskey", "stskpass");
      passwords.put("alice", "clarinet");
      return passwords;
   }
}
Copy to Clipboard Toggle word wrap
A.8.2.2.5. 加密属性和密钥存储文件

WSS4J 的 Crypto 实施通过包含 Crypto 配置数据的 Java 属性文件来加载和配置。文件包含特定于实施的属性,如密钥存储位置、密码、默认别名等。此应用程序正在使用 Merlin 实施。stsKeystore.properties 文件包含此信息。

servicestore.jks 文件是 Java KeyStore(JKS)存储库。它包含 myservicekey 和 mystskey 的自签名证书。

注意

自签名证书不适合在生产环境中使用。

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=stsspass
org.apache.ws.security.crypto.merlin.keystore.file=stsstore.jks
Copy to Clipboard Toggle word wrap
A.8.2.2.6. 默认 MANIFEST.MF

此应用程序需要访问 org.jboss.ws.cxf.jbossws-cxf 中提供的 JBossWS 和 Apache CXF API。还需要 org.jboss.ws.cxf.sts 模块在 SampleSTS 构造器中构建 STS 配置。dependency 语句指示服务器在部署时提供它们。

Manifest-Version: 1.0
Dependencies: org.jboss.ws.cxf.jbossws-cxf-client,org.jboss.ws.cxf.sts
Copy to Clipboard Toggle word wrap

A.8.2.3. Web Service Requester

本节详细介绍了调用实现端点安全性的 Web 服务的关键元素,如 SAML Bearer 场景中所述。讨论的组件包括:

A.8.2.3.1. Web 服务请求者实施

ws-requester (客户端)使用了标准步骤来创建对 Web 服务的引用。为解决端点安全要求,Web 服务的"请求上下文"配置了消息生成所需的信息。此外,与 STS 通信的 STSClient 也配置了类似的值。

注意

以 a .it 后缀结尾的密钥字符串将这些设置标记为属于 STSClient。内部 Apache CXF 代码将此信息分配到此服务调用自动生成的 STSClient

还有一种设置 STSCLient 的方法。用户可以提供自己的 STSClient 实例。Apache CXF 代码使用此对象,不自动生成一个对象。以这种方式提供 STSClient 时,用户必须为其提供 org.apache.cxf.Bus,配置键不得具有 .it 后缀。这可用于 ActAsOnBehalfOf 示例。

String serviceURL = "https://" + getServerHost() + ":8443/jaxws-samples-wsse-policy-trust-bearer/BearerService";

final QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/bearerwssecuritypolicy", "BearerService");
Service service = Service.create(new URL(serviceURL + "?wsdl"), serviceName);
BearerIface proxy = (BearerIface) service.getPort(BearerIface.class);

Map<String, Object> ctx = ((BindingProvider)proxy).getRequestContext();

// set the security related configuration information for the service "request"
ctx.put(SecurityConstants.CALLBACK_HANDLER, new ClientCallbackHandler());
ctx.put(SecurityConstants.SIGNATURE_PROPERTIES,
  Thread.currentThread().getContextClassLoader().getResource(
  "META-INF/clientKeystore.properties"));
ctx.put(SecurityConstants.ENCRYPT_PROPERTIES,
  Thread.currentThread().getContextClassLoader().getResource(
  "META-INF/clientKeystore.properties"));
ctx.put(SecurityConstants.SIGNATURE_USERNAME, "myclientkey");
ctx.put(SecurityConstants.ENCRYPT_USERNAME, "myservicekey");

//-- Configuration settings that will be transfered to the STSClient
// "alice" is the name provided for the WSS Username. Her password will
// be retreived from the ClientCallbackHander by the STSClient.
ctx.put(SecurityConstants.USERNAME + ".it", "alice");
ctx.put(SecurityConstants.CALLBACK_HANDLER + ".it", new ClientCallbackHandler());
ctx.put(SecurityConstants.ENCRYPT_PROPERTIES + ".it",
  Thread.currentThread().getContextClassLoader().getResource(
  "META-INF/clientKeystore.properties"));
ctx.put(SecurityConstants.ENCRYPT_USERNAME + ".it", "mystskey");
ctx.put(SecurityConstants.STS_TOKEN_USERNAME + ".it", "myclientkey");
ctx.put(SecurityConstants.STS_TOKEN_PROPERTIES + ".it",
  Thread.currentThread().getContextClassLoader().getResource(
  "META-INF/clientKeystore.properties"));
ctx.put(SecurityConstants.STS_TOKEN_USE_CERT_FOR_KEYINFO + ".it", "true");

proxy.sayHello();
Copy to Clipboard Toggle word wrap
A.8.2.3.2. ClientCallbackHandler

ClientCallbackHandler 是 WSS4J Crypto API 的回调处理程序。它用于在密钥存储中获取私钥的密码。此类使 Apache CXF 能够检索用于消息签名的用户名密码。

注意

这里提供了用户 alice 和密码。此信息不在(JKS)密钥存储中,而是在安全域中提供。它在 jbossws-users.properties 文件中声明。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.shared;

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;

public class ClientCallbackHandler implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof WSPasswordCallback) {
                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
                if ("myclientkey".equals(pc.getIdentifier())) {
                    pc.setPassword("ckpass");
                    break;
                } else if ("alice".equals(pc.getIdentifier())) {
                    pc.setPassword("clarinet");
                    break;
                } else if ("bob".equals(pc.getIdentifier())) {
                    pc.setPassword("trombone");
                    break;
                } else if ("myservicekey".equals(pc.getIdentifier())) {  // rls test  added for bearer test
                   pc.setPassword("skpass");
                   break;
                }
            }
        }
    }
}
Copy to Clipboard Toggle word wrap
A.8.2.3.3. 加密属性和密钥存储文件

WSS4J 的 Crypto 实施通过包含 Crypto 配置数据的 Java 属性文件来加载和配置。文件包含特定于实施的属性,如密钥存储位置、密码、默认别名等。此应用程序正在使用 Merlin 实施。clientKeystore.properties 文件包含此信息。

clientstore.jks 文件是 Java KeyStore(JKS)存储库。它包含 myservicekey 和 mystskey 的自签名证书。

注意

自签名证书不适合在生产环境中使用。

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=cspass
org.apache.ws.security.crypto.merlin.keystore.alias=myclientkey
org.apache.ws.security.crypto.merlin.keystore.file=META-INF/clientstore.jks
Copy to Clipboard Toggle word wrap

A.8.3. 场景:OnehalfOf WS-Trust

OnBehalfOf 功能用于使用代理模式的情况。在这种情况下,客户端无法直接访问 STS,而是通过代理网关进行通信。代理网关验证调用者,并将调用者的信息放入 RequestSecurityToken (RST)的 OnBehalfOf 元素中,以用于处理。生成的令牌仅包含与代理客户端相关的声明,使代理对颁发的令牌的接收器完全透明。

OnBehalfOf 不仅仅是 RST 中的新子元素。它在与 STS 协商令牌时提供有关原始调用者的额外信息。OnBehalfOf 元素通常采用令牌形式,其身份声明(如名称、角色和授权代码)供客户端访问服务。

OnBehalfOf 方案是基本 WS-Trust 场景的扩展。在本例中,OnBehalfOf 服务代表用户调用 ws-service。对基本场景的代码仅作几处补充。添加了 OnBehalfOf Web 服务提供商和回调处理程序。OnBehalfOf Web 服务的 WSDL 采用了与 ws-provider 相同的安全策略。UsernameTokenCallbackHandler 是与 ActAs 共享的实用程序。它为 OnBehalfOf 元素生成内容。最后,STS 中也添加了代码,OnBehalfOfActAs 共享了相同的代码。

A.8.3.1. Web 服务提供商

本节提供已更新的基本 WS-Trust 场景中的 Web 服务元素,以满足 OnBehalfOf 示例 的要求。这些组件包括:

A.8.3.1.1. Web 服务提供商 WSDL

OnBehalfOf Web 服务提供商的 WSDL 是 ws-provider 的 WSDL 的 克隆。wsp:Policy 部分是相同的。对服务端点、target Namespace、portType绑定 名称和 服务进行了更新

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions targetNamespace="http://www.jboss.org/jbossws/ws-extensions/onbehalfofwssecuritypolicy" name="OnBehalfOfService"
             xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/onbehalfofwssecuritypolicy"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:wsp="http://www.w3.org/ns/ws-policy"
             xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
             xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
             xmlns:wsaws="http://www.w3.org/2005/08/addressing"
             xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
             xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
    <types>
        <xsd:schema>
            <xsd:import namespace="http://www.jboss.org/jbossws/ws-extensions/onbehalfofwssecuritypolicy"
                  schemaLocation="OnBehalfOfService_schema1.xsd"/>
        </xsd:schema>
    </types>
    <message name="sayHello">
        <part name="parameters" element="tns:sayHello"/>
    </message>
    <message name="sayHelloResponse">
        <part name="parameters" element="tns:sayHelloResponse"/>
    </message>
    <portType name="OnBehalfOfServiceIface">
        <operation name="sayHello">
            <input message="tns:sayHello"/>
            <output message="tns:sayHelloResponse"/>
        </operation>
    </portType>
    <binding name="OnBehalfOfServicePortBinding" type="tns:OnBehalfOfServiceIface">
        <wsp:PolicyReference URI="#AsymmetricSAML2Policy" />
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
        <operation name="sayHello">
            <soap:operation soapAction=""/>
            <input>
                <soap:body use="literal"/>
                <wsp:PolicyReference URI="#Input_Policy" />
            </input>
            <output>
                <soap:body use="literal"/>
                <wsp:PolicyReference URI="#Output_Policy" />
            </output>
        </operation>
    </binding>
    <service name="OnBehalfOfService">
        <port name="OnBehalfOfServicePort" binding="tns:OnBehalfOfServicePortBinding">
            <soap:address location="http://@jboss.bind.address@:8080/jaxws-samples-wsse-policy-trust-onbehalfof/OnBehalfOfService"/>
        </port>
    </service>
</definitions>
Copy to Clipboard Toggle word wrap
A.8.3.1.2. Web 服务提供商接口

OnBehalfOfServiceIface Web 服务提供商接口类是一个简单的 Web 服务定义。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.onbehalfof;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
(
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/onbehalfofwssecuritypolicy"
)
public interface OnBehalfOfServiceIface {
   @WebMethod
   String sayHello();
}
Copy to Clipboard Toggle word wrap
A.8.3.1.3. Web 服务提供商实施

OnBehalfOfServiceImpl Web 服务提供商实施类是一个简单的 POJO。它使用标准的 WebService 注释来定义服务端点和两个 Apache WSS4J 注释,即 EndpointPropertiesEndpointProperty,用于为 Apache CXF 运行时配置端点。提供的 WSS4J 配置信息用于 WSS4J 的 Crypto Merlin 实施。

OnBehalfOfService Impl 代表用户调用 ServiceImplsetupService 方法执行所需的配置设置。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.onbehalfof;

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.annotations.EndpointProperties;
import org.apache.cxf.annotations.EndpointProperty;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.cxf.ws.security.trust.STSClient;
import org.jboss.test.ws.jaxws.samples.wsse.policy.trust.service.ServiceIface;
import org.jboss.test.ws.jaxws.samples.wsse.policy.trust.shared.WSTrustAppUtils;

import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import java.net.*;
import java.util.Map;

@WebService
(
   portName = "OnBehalfOfServicePort",
   serviceName = "OnBehalfOfService",
   wsdlLocation = "WEB-INF/wsdl/OnBehalfOfService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/onbehalfofwssecuritypolicy",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.onbehalfof.OnBehalfOfServiceIface"
)

@EndpointProperties(value = {
      @EndpointProperty(key = "ws-security.signature.username", value = "myactaskey"),
      @EndpointProperty(key = "ws-security.signature.properties", value =  "actasKeystore.properties"),
      @EndpointProperty(key = "ws-security.encryption.properties", value = "actasKeystore.properties"),
      @EndpointProperty(key = "ws-security.callback-handler", value = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.onbehalfof.OnBehalfOfCallbackHandler")
})

public class OnBehalfOfServiceImpl implements OnBehalfOfServiceIface {
   public String sayHello() {
      try {

         ServiceIface proxy = setupService();
         return "OnBehalfOf " + proxy.sayHello();

      } catch (MalformedURLException e) {
         e.printStackTrace();
      }
      return null;
   }

   /**
    *
    * @return
    * @throws MalformedURLException
    */
   private  ServiceIface setupService()throws MalformedURLException {
      ServiceIface proxy = null;
      Bus bus = BusFactory.newInstance().createBus();

      try {
         BusFactory.setThreadDefaultBus(bus);

         final String serviceURL = "http://" + WSTrustAppUtils.getServerHost() + ":8080/jaxws-samples-wsse-policy-trust/SecurityService";
         final QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wssecuritypolicy", "SecurityService");
         final URL wsdlURL = new URL(serviceURL + "?wsdl");
         Service service = Service.create(wsdlURL, serviceName);
         proxy = (ServiceIface) service.getPort(ServiceIface.class);

         Map<String, Object> ctx = ((BindingProvider) proxy).getRequestContext();
         ctx.put(SecurityConstants.CALLBACK_HANDLER, new OnBehalfOfCallbackHandler());

         ctx.put(SecurityConstants.SIGNATURE_PROPERTIES,
            Thread.currentThread().getContextClassLoader().getResource(
            "actasKeystore.properties" ));
         ctx.put(SecurityConstants.SIGNATURE_USERNAME, "myactaskey" );
         ctx.put(SecurityConstants.ENCRYPT_PROPERTIES,
            Thread.currentThread().getContextClassLoader().getResource(
            "../../META-INF/clientKeystore.properties" ));
         ctx.put(SecurityConstants.ENCRYPT_USERNAME, "myservicekey");

         STSClient stsClient = new STSClient(bus);
         Map<String, Object> props = stsClient.getProperties();
         props.put(SecurityConstants.USERNAME, "bob");
         props.put(SecurityConstants.ENCRYPT_USERNAME, "mystskey");
         props.put(SecurityConstants.STS_TOKEN_USERNAME, "myactaskey" );
         props.put(SecurityConstants.STS_TOKEN_PROPERTIES,
            Thread.currentThread().getContextClassLoader().getResource(
            "actasKeystore.properties" ));
         props.put(SecurityConstants.STS_TOKEN_USE_CERT_FOR_KEYINFO, "true");

         ctx.put(SecurityConstants.STS_CLIENT, stsClient);

      } finally {
         bus.shutdown(true);
      }

      return proxy;
   }

}
Copy to Clipboard Toggle word wrap
A.8.3.1.4. OnBehalfOfCallbackHandler Class

OnBehalfOfCallbackHandler 是 WSS4J Crypto API 的回调处理程序。它用于在密钥存储中获取私钥的密码。此类使 Apache CXF 能够检索用于消息签名的用户名密码。此类已被更新,返回此服务的密码 myactaskeyOnBehalfOf 用户 alice

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.onbehalfof;

import org.jboss.wsf.stack.cxf.extensions.security.PasswordCallbackHandler;
import java.util.HashMap;
import java.util.Map;

public class OnBehalfOfCallbackHandler extends PasswordCallbackHandler {

   public OnBehalfOfCallbackHandler() {
      super(getInitMap());
   }

   private static Map<String, String> getInitMap() {
      Map<String, String> passwords = new HashMap<String, String>();
      passwords.put("myactaskey", "aspass");
      passwords.put("alice", "clarinet");
      passwords.put("bob", "trombone");
      return passwords;
   }

}
Copy to Clipboard Toggle word wrap

A.8.3.2. Web Service Requester

本节详细介绍了 WS -Trust 场景中的 ws-requester 元素,这些元素已更新,以满足 OnBehalfOf 示例 的要求。该组件为:

A.8.3.2.1. OnBehalfOf Web 服务请求器实施类

客户端 OnBehalfOf ws-requester 使用标准步骤在前四行中创建对 Web 服务的引用。为满足端点安全要求,Web 服务的请求上下文使用 BindingProvider 配置。通过其提供消息生成所需的信息。此部分中声明了 OnBehalfOf 用户 alice,并向 STSClient 提供 callbackHandlerUsernameTokenCallbackHandler,用于生成 OnBehalfOf 消息元素的内容。在本例中,将创建一个 STSClient 对象,并提供给代理的请求上下文。另一种方法是提供带有 .it 后缀的键,如基本场景客户端中所执行的操作一样。OnBehalfOf 的使用通过 stsClient.setOnBehalfOf 调用方法进行配置。另一种方法是在 properties 映射中使用 key SecurityConstants.STS_TOKEN_ON_BEHALF_OF 和一个值。

final QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/onbehalfofwssecuritypolicy", "OnBehalfOfService");
final URL wsdlURL = new URL(serviceURL + "?wsdl");
Service service = Service.create(wsdlURL, serviceName);
OnBehalfOfServiceIface proxy = (OnBehalfOfServiceIface) service.getPort(OnBehalfOfServiceIface.class);


Bus bus = BusFactory.newInstance().createBus();
try {

    BusFactory.setThreadDefaultBus(bus);

    Map<String, Object> ctx = proxy.getRequestContext();

    ctx.put(SecurityConstants.CALLBACK_HANDLER, new ClientCallbackHandler());
    ctx.put(SecurityConstants.ENCRYPT_PROPERTIES,
        Thread.currentThread().getContextClassLoader().getResource(
        "META-INF/clientKeystore.properties"));
    ctx.put(SecurityConstants.ENCRYPT_USERNAME, "myactaskey");
    ctx.put(SecurityConstants.SIGNATURE_PROPERTIES,
        Thread.currentThread().getContextClassLoader().getResource(
        "META-INF/clientKeystore.properties"));
    ctx.put(SecurityConstants.SIGNATURE_USERNAME, "myclientkey");

    // user and password OnBehalfOf user
    // UsernameTokenCallbackHandler will extract this information when called
    ctx.put(SecurityConstants.USERNAME,"alice");
    ctx.put(SecurityConstants.PASSWORD, "clarinet");

    STSClient stsClient = new STSClient(bus);

    // Providing the STSClient the mechanism to create the claims contents for OnBehalfOf
    stsClient.setOnBehalfOf(new UsernameTokenCallbackHandler());

    Map<String, Object> props = stsClient.getProperties();
    props.put(SecurityConstants.CALLBACK_HANDLER, new ClientCallbackHandler());
    props.put(SecurityConstants.ENCRYPT_PROPERTIES,
        Thread.currentThread().getContextClassLoader().getResource(
        "META-INF/clientKeystore.properties"));
    props.put(SecurityConstants.ENCRYPT_USERNAME, "mystskey");
    props.put(SecurityConstants.STS_TOKEN_USERNAME, "myclientkey");
    props.put(SecurityConstants.STS_TOKEN_PROPERTIES,
        Thread.currentThread().getContextClassLoader().getResource(
        "META-INF/clientKeystore.properties"));
    props.put(SecurityConstants.STS_TOKEN_USE_CERT_FOR_KEYINFO, "true");

    ctx.put(SecurityConstants.STS_CLIENT, stsClient);

} finally {
    bus.shutdown(true);
}
proxy.sayHello();
Copy to Clipboard Toggle word wrap

A.8.4. 场景:ActAs WS-Trust

ActA 功能用于需要复合委派的情况。它通常用于多层系统中,其中的应用代表登录用户调用服务,或者服务代表原始调用者调用其他服务。

actionas 不仅仅是 RequestSecurityToken (RST)中的新子元素。它在与 STS 协商令牌时提供有关原始调用者的额外信息。ActAs 元素通常采用令牌的形式,其身份声明(如名称、角色和授权代码)供客户端访问服务。

ActA 场景是基本 WS-Trust 场景的扩展。在本例中,ActAs 服务代表用户调用 ws-service。对基本场景的代码仅作几处补充。添加了 ActAs Web 服务提供商和回调处理程序。ActAs Web 服务的 WSDL 采用了与 ws-provider 相同的安全策略。UsernameTokenCallbackHandler 是一个新实用程序,可为 ActAs 元素生成内容。最后,STS 中添加了一些代码来支持 ActAs 请求。

A.8.4.1. Web 服务提供商

本节详细介绍了已更改的基本 WS-Trust 场景中的 Web 服务元素,以满足 ActAs 示例 的需求。这些组件包括:

A.8.4.1.1. Web 服务提供商 WSDL

ActAs Web 服务提供商的 WSDL 是 ws-provider 的 WSDL 的 克隆。wsp:Policy 部分是相同的。服务端点、target Namespace、port Type绑定 名称和 服务 都有更改。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions targetNamespace="http://www.jboss.org/jbossws/ws-extensions/actaswssecuritypolicy" name="ActAsService"
             xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/actaswssecuritypolicy"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:wsp="http://www.w3.org/ns/ws-policy"
             xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
             xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
             xmlns:wsaws="http://www.w3.org/2005/08/addressing"
             xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
             xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
    <types>
        <xsd:schema>
            <xsd:import namespace="http://www.jboss.org/jbossws/ws-extensions/actaswssecuritypolicy"
                    schemaLocation="ActAsService_schema1.xsd"/>
        </xsd:schema>
    </types>
    <message name="sayHello">
        <part name="parameters" element="tns:sayHello"/>
    </message>
    <message name="sayHelloResponse">
        <part name="parameters" element="tns:sayHelloResponse"/>
    </message>
    <portType name="ActAsServiceIface">
        <operation name="sayHello">
            <input message="tns:sayHello"/>
            <output message="tns:sayHelloResponse"/>
        </operation>
    </portType>
    <binding name="ActAsServicePortBinding" type="tns:ActAsServiceIface">
        <wsp:PolicyReference URI="#AsymmetricSAML2Policy" />
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
        <operation name="sayHello">
            <soap:operation soapAction=""/>
            <input>
                <soap:body use="literal"/>
                <wsp:PolicyReference URI="#Input_Policy" />
            </input>
            <output>
                <soap:body use="literal"/>
                <wsp:PolicyReference URI="#Output_Policy" />
            </output>
        </operation>
    </binding>
    <service name="ActAsService">
        <port name="ActAsServicePort" binding="tns:ActAsServicePortBinding">
            <soap:address location="http://@jboss.bind.address@:8080/jaxws-samples-wsse-policy-trust-actas/ActAsService"/>
        </port>
    </service>

</definitions>
Copy to Clipboard Toggle word wrap
A.8.4.1.2. Web 服务提供商接口

ActAsServiceIface Web 服务提供商界面类是一个简单的 Web 服务定义。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.actas;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
(
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/actaswssecuritypolicy"
)
public interface ActAsServiceIface {
   @WebMethod
   String sayHello();
}
Copy to Clipboard Toggle word wrap
A.8.4.1.3. Web 服务提供商实施

ActAsServiceImpl Web 服务提供商实施类是一个简单的 POJO。它使用标准的 WebService 注释来定义服务端点和两个 Apache WSS4J 注释(Ed pointPropertiesEndpointProperty ),用于为 Apache CXF 运行时配置端点。提供的 WSS4J 配置信息用于 WSS4J 的 Crypto Merlin 实施。

ActAsServiceImpl 代表用户调用 ServiceImplsetupService 方法执行所需的配置设置。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.actas;

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.annotations.EndpointProperties;
import org.apache.cxf.annotations.EndpointProperty;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.cxf.ws.security.trust.STSClient;
import org.jboss.test.ws.jaxws.samples.wsse.policy.trust.service.ServiceIface;
import org.jboss.test.ws.jaxws.samples.wsse.policy.trust.shared.WSTrustAppUtils;

import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

@WebService
(
   portName = "ActAsServicePort",
   serviceName = "ActAsService",
   wsdlLocation = "WEB-INF/wsdl/ActAsService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/actaswssecuritypolicy",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.actas.ActAsServiceIface"
)

@EndpointProperties(value = {
      @EndpointProperty(key = "ws-security.signature.username", value = "myactaskey"),
      @EndpointProperty(key = "ws-security.signature.properties", value =  "actasKeystore.properties"),
      @EndpointProperty(key = "ws-security.encryption.properties", value = "actasKeystore.properties"),
      @EndpointProperty(key = "ws-security.callback-handler", value = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.actas.ActAsCallbackHandler")
})

public class ActAsServiceImpl implements ActAsServiceIface {
   public String sayHello() {
      try {
         ServiceIface proxy = setupService();
         return "ActAs " + proxy.sayHello();
      } catch (MalformedURLException e) {
         e.printStackTrace();
      }
      return null;
   }

   private  ServiceIface setupService()throws MalformedURLException {
      ServiceIface proxy = null;
      Bus bus = BusFactory.newInstance().createBus();

      try {
         BusFactory.setThreadDefaultBus(bus);

         final String serviceURL = "http://" + WSTrustAppUtils.getServerHost() + ":8080/jaxws-samples-wsse-policy-trust/SecurityService";
         final QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wssecuritypolicy", "SecurityService");
         final URL wsdlURL = new URL(serviceURL + "?wsdl");
         Service service = Service.create(wsdlURL, serviceName);
         proxy = (ServiceIface) service.getPort(ServiceIface.class);

         Map<String, Object> ctx = ((BindingProvider) proxy).getRequestContext();
         ctx.put(SecurityConstants.CALLBACK_HANDLER, new ActAsCallbackHandler());

         ctx.put(SecurityConstants.SIGNATURE_PROPERTIES,
            Thread.currentThread().getContextClassLoader().getResource("actasKeystore.properties" ));
         ctx.put(SecurityConstants.SIGNATURE_USERNAME, "myactaskey" );
         ctx.put(SecurityConstants.ENCRYPT_PROPERTIES,
            Thread.currentThread().getContextClassLoader().getResource("../../META-INF/clientKeystore.properties" ));
         ctx.put(SecurityConstants.ENCRYPT_USERNAME, "myservicekey");

         STSClient stsClient = new STSClient(bus);
         Map<String, Object> props = stsClient.getProperties();
         props.put(SecurityConstants.USERNAME, "alice");
         props.put(SecurityConstants.ENCRYPT_USERNAME, "mystskey");
         props.put(SecurityConstants.STS_TOKEN_USERNAME, "myactaskey" );
         props.put(SecurityConstants.STS_TOKEN_PROPERTIES,
            Thread.currentThread().getContextClassLoader().getResource("actasKeystore.properties" ));
         props.put(SecurityConstants.STS_TOKEN_USE_CERT_FOR_KEYINFO, "true");

         ctx.put(SecurityConstants.STS_CLIENT, stsClient);

      } finally {
         bus.shutdown(true);
      }

      return proxy;
   }

}
Copy to Clipboard Toggle word wrap
A.8.4.1.4. ActAsCallbackHandler Class

ActAsCallbackHandler 是 WSS4J Crypto API 的回调处理程序。它用于在密钥存储中获取私钥的密码。此类使 Apache CXF 能够检索用于消息签名的用户名密码。此类已更新,以返回此服务的密码,即 myactaskeyActAs 用户 alice

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.actas;

import org.jboss.wsf.stack.cxf.extensions.security.PasswordCallbackHandler;
import java.util.HashMap;
import java.util.Map;

public class ActAsCallbackHandler extends PasswordCallbackHandler {

   public ActAsCallbackHandler() {
      super(getInitMap());
   }

   private static Map<String, String> getInitMap() {
      Map<String, String> passwords = new HashMap<String, String>();
      passwords.put("myactaskey", "aspass");
      passwords.put("alice", "clarinet");
      return passwords;
   }
}
Copy to Clipboard Toggle word wrap
A.8.4.1.5. UsernameTokenCallbackHandler

RequestSecurityTokenActAsOnBeholdOf 子元素必须定义为 WSSE UsernameTokens。此实用程序生成正确格式化的元素。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.shared;

import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.cxf.ws.security.trust.delegation.DelegationCallback;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.message.token.UsernameToken;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.util.Map;

/**
* A utility to provide the 3 different input parameter types for jaxws property
* "ws-security.sts.token.act-as" and "ws-security.sts.token.on-behalf-of".
* This implementation obtains a username and password via the jaxws property
* "ws-security.username" and "ws-security.password" respectively, as defined
* in SecurityConstants.  It creates a wss UsernameToken to be used as the
* delegation token.
*/

public class UsernameTokenCallbackHandler implements CallbackHandler {

   public void handle(Callback[] callbacks)
      throws IOException, UnsupportedCallbackException {
      for (int i = 0; i < callbacks.length; i++) {
         if (callbacks[i] instanceof DelegationCallback) {
            DelegationCallback callback = (DelegationCallback) callbacks[i];
            Message message = callback.getCurrentMessage();

            String username =
               (String)message.getContextualProperty(SecurityConstants.USERNAME);
            String password =
               (String)message.getContextualProperty(SecurityConstants.PASSWORD);
            if (username != null) {
               Node contentNode = message.getContent(Node.class);
               Document doc = null;
               if (contentNode != null) {
                  doc = contentNode.getOwnerDocument();
               } else {
                  doc = DOMUtils.createDocument();
               }
               UsernameToken usernameToken = createWSSEUsernameToken(username,password, doc);
               callback.setToken(usernameToken.getElement());
            }
         } else {
            throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
         }
      }
   }

   /**
    * Provide UsernameToken as a string.
    * @param ctx
    * @return
    */
   public String getUsernameTokenString(Map<String, Object> ctx){
      Document doc = DOMUtils.createDocument();
      String result = null;
      String username = (String)ctx.get(SecurityConstants.USERNAME);
      String password = (String)ctx.get(SecurityConstants.PASSWORD);
      if (username != null) {
         UsernameToken usernameToken = createWSSEUsernameToken(username,password, doc);
         result = toString(usernameToken.getElement().getFirstChild().getParentNode());
      }
      return result;
   }

   /**
    *
    * @param username
    * @param password
    * @return
    */
   public String getUsernameTokenString(String username, String password){
      Document doc = DOMUtils.createDocument();
      String result = null;
      if (username != null) {
         UsernameToken usernameToken = createWSSEUsernameToken(username,password, doc);
         result = toString(usernameToken.getElement().getFirstChild().getParentNode());
      }
      return result;
   }

   /**
    * Provide UsernameToken as a DOM Element.
    * @param ctx
    * @return
    */
   public Element getUsernameTokenElement(Map<String, Object> ctx){
      Document doc = DOMUtils.createDocument();
      Element result = null;
      UsernameToken usernameToken = null;
         String username = (String)ctx.get(SecurityConstants.USERNAME);
      String password = (String)ctx.get(SecurityConstants.PASSWORD);
      if (username != null) {
         usernameToken = createWSSEUsernameToken(username,password, doc);
         result = usernameToken.getElement();
      }
      return result;
   }

   /**
    *
    * @param username
    * @param password
    * @return
    */
   public Element getUsernameTokenElement(String username, String password){
      Document doc = DOMUtils.createDocument();
      Element result = null;
      UsernameToken usernameToken = null;
      if (username != null) {
         usernameToken = createWSSEUsernameToken(username,password, doc);
         result = usernameToken.getElement();
      }
      return result;
   }

   private UsernameToken createWSSEUsernameToken(String username, String password, Document doc) {

      UsernameToken usernameToken = new UsernameToken(true, doc,
         (password == null)? null: WSConstants.PASSWORD_TEXT);
      usernameToken.setName(username);
      usernameToken.addWSUNamespace();
      usernameToken.addWSSENamespace();
      usernameToken.setID("id-" + username);

      if (password != null){
         usernameToken.setPassword(password);
      }

      return usernameToken;
   }


   private String toString(Node node) {
      String str = null;

      if (node != null) {
         DOMImplementationLS lsImpl = (DOMImplementationLS)
            node.getOwnerDocument().getImplementation().getFeature("LS", "3.0");
         LSSerializer serializer = lsImpl.createLSSerializer();
         serializer.getDomConfig().setParameter("xml-declaration", false); //by default its true, so set it to false to get String without xml-declaration
         str = serializer.writeToString(node);
      }
      return str;
   }

}
Copy to Clipboard Toggle word wrap
A.8.4.1.6. crypto 属性和密钥存储文件

ActA 服务必须提供自己的凭据。创建必要的 actasKeystore.properties 属性文件和 actasstore.jks 密钥存储。

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=aapass
org.apache.ws.security.crypto.merlin.keystore.alias=myactaskey
org.apache.ws.security.crypto.merlin.keystore.file=actasstore.jks
Copy to Clipboard Toggle word wrap
A.8.4.1.7. 默认 MANIFEST.MF

此应用程序需要访问 org.jboss.ws.cxf.jbossws-cxf 中提供的 JBossWS 和 Apache CXF API。在处理 ActAsOnBehalfOf 扩展时,还需要 org.jboss.ws.cxf.sts 模块。dependency 语句指示服务器在部署时提供它们。

Manifest-Version: 1.0
Dependencies: org.jboss.ws.cxf.jbossws-cxf-client, org.jboss.ws.cxf.sts
Copy to Clipboard Toggle word wrap

A.8.4.2. 安全令牌服务

本节详细介绍了 WS-Trust 基本场景中的 STS 元素以满足 ActAs 示例的需求。这些组件包括:

A.8.4.2.1. STS 实施类

通过地址扩展允许令牌收件人的声明接受 ActAs 地址和 OnBehalfOf 地址。地址指定为 reg-ex 模式。

TokenIsueOperation 要求提供 UsernameToken 验证器 类来验证 OnBehalfOf 的内容,并提供 UsernameTokenDelegationHandler 类,以处理 OnBehalfOf 用户的 ActAs 的令牌委派请求。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.sts;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import javax.xml.ws.WebServiceProvider;

import org.apache.cxf.annotations.EndpointProperties;
import org.apache.cxf.annotations.EndpointProperty;
import org.apache.cxf.interceptor.InInterceptors;
import org.apache.cxf.sts.StaticSTSProperties;
import org.apache.cxf.sts.operation.TokenIssueOperation;
import org.apache.cxf.sts.operation.TokenValidateOperation;
import org.apache.cxf.sts.service.ServiceMBean;
import org.apache.cxf.sts.service.StaticService;
import org.apache.cxf.sts.token.delegation.UsernameTokenDelegationHandler;
import org.apache.cxf.sts.token.provider.SAMLTokenProvider;
import org.apache.cxf.sts.token.validator.SAMLTokenValidator;
import org.apache.cxf.sts.token.validator.UsernameTokenValidator;
import org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider;

@WebServiceProvider(serviceName = "SecurityTokenService",
      portName = "UT_Port",
      targetNamespace = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/",
      wsdlLocation = "WEB-INF/wsdl/ws-trust-1.4-service.wsdl")
//dependency on org.apache.cxf module or on module that exports org.apache.cxf (e.g. org.jboss.ws.cxf.jbossws-cxf-client) is needed, otherwise Apache CXF annotations are ignored
@EndpointProperties(value = {
      @EndpointProperty(key = "ws-security.signature.username", value = "mystskey"),
      @EndpointProperty(key = "ws-security.signature.properties", value = "stsKeystore.properties"),
      @EndpointProperty(key = "ws-security.callback-handler", value = "org.jboss.test.ws.jaxws.samples.wsse.policy.trust.sts.STSCallbackHandler"),
      @EndpointProperty(key = "ws-security.validate.token", value = "false") //to let the JAAS integration deal with validation through the interceptor below
})
@InInterceptors(interceptors = {"org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingPolicyInterceptor"})
public class SampleSTS extends SecurityTokenServiceProvider {
   public SampleSTS() throws Exception {
      super();

      StaticSTSProperties props = new StaticSTSProperties();
      props.setSignatureCryptoProperties("stsKeystore.properties");
      props.setSignatureUsername("mystskey");
      props.setCallbackHandlerClass(STSCallbackHandler.class.getName());
      props.setIssuer("DoubleItSTSIssuer");

      List<ServiceMBean> services = new LinkedList<ServiceMBean>();
      StaticService service = new StaticService();
      service.setEndpoints(Arrays.asList(
         "http://localhost:(\\d)*/jaxws-samples-wsse-policy-trust/SecurityService",
         "http://\\[::1\\]:(\\d)*/jaxws-samples-wsse-policy-trust/SecurityService",
         "http://\\[0:0:0:0:0:0:0:1\\]:(\\d)*/jaxws-samples-wsse-policy-trust/SecurityService",

         "http://localhost:(\\d)*/jaxws-samples-wsse-policy-trust-actas/ActAsService",
         "http://\\[::1\\]:(\\d)*/jaxws-samples-wsse-policy-trust-actas/ActAsService",
         "http://\\[0:0:0:0:0:0:0:1\\]:(\\d)*/jaxws-samples-wsse-policy-trust-actas/ActAsService",

         "http://localhost:(\\d)*/jaxws-samples-wsse-policy-trust-onbehalfof/OnBehalfOfService",
         "http://\\[::1\\]:(\\d)*/jaxws-samples-wsse-policy-trust-onbehalfof/OnBehalfOfService",
         "http://\\[0:0:0:0:0:0:0:1\\]:(\\d)*/jaxws-samples-wsse-policy-trust-onbehalfof/OnBehalfOfService"
      ));
      services.add(service);

      TokenIssueOperation issueOperation = new TokenIssueOperation();
      issueOperation.setServices(services);
      issueOperation.getTokenProviders().add(new SAMLTokenProvider());
      // required for OnBehalfOf
      issueOperation.getTokenValidators().add(new UsernameTokenValidator());
      // added for OnBehalfOf and ActAs
      issueOperation.getDelegationHandlers().add(new UsernameTokenDelegationHandler());
      issueOperation.setStsProperties(props);

      TokenValidateOperation validateOperation = new TokenValidateOperation();
      validateOperation.getTokenValidators().add(new SAMLTokenValidator());
      validateOperation.setStsProperties(props);

      this.setIssueOperation(issueOperation);
      this.setValidateOperation(validateOperation);
   }
}
Copy to Clipboard Toggle word wrap
A.8.4.2.2. STSCallbackHandler 类

ActAs 示例添加用户 alice 和对应的密码。

package org.jboss.test.ws.jaxws.samples.wsse.policy.trust.sts;

import java.util.HashMap;
import java.util.Map;

import org.jboss.wsf.stack.cxf.extensions.security.PasswordCallbackHandler;

public class STSCallbackHandler extends PasswordCallbackHandler {
   public STSCallbackHandler() {
      super(getInitMap());
   }

   private static Map<String, String> getInitMap() {
      Map<String, String> passwords = new HashMap<String, String>();
      passwords.put("mystskey", "stskpass");
      passwords.put("alice", "clarinet");
      return passwords;
   }
}
Copy to Clipboard Toggle word wrap
A.8.4.2.3. Web Service Requester

本节详细介绍了 WS-Trust 环境中的基本 WS -Trust 场景中的 ws-requester 元素,这些元素已更改为满足 ActAs 示例 的要求。该组件为:

A.8.4.2.4. Web 服务请求者实施类

作为客户端 ActAs ws-requester 使用标准步骤在前四行中创建对 Web 服务的引用。为满足端点安全要求,Web 服务的请求上下文配置为使用 BindingProvider 来提供消息生成所需的信息。ActAs 用户 myactaskey 在此部分中声明,UsernameTokenCallbackHandler 用于向 STSClient 提供 ActAs 元素的内容。在本例中,将创建一个 STSClient 对象,并提供给代理的请求上下文。另一种方法是提供带有 .it 后缀的键,如基本场景客户端中所执行的操作一样。ActAs 的使用通过利用 SecurityConstants.STS_TOKEN_ACT_AS 键的属性映射进行配置。另一种方法是使用 STSClient.setActAs 方法。

final QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/actaswssecuritypolicy", "ActAsService");
final URL wsdlURL = new URL(serviceURL + "?wsdl");
Service service = Service.create(wsdlURL, serviceName);
ActAsServiceIface proxy = (ActAsServiceIface) service.getPort(ActAsServiceIface.class);

Bus bus = BusFactory.newInstance().createBus();
try {
    BusFactory.setThreadDefaultBus(bus);

    Map<String, Object> ctx = proxy.getRequestContext();

    ctx.put(SecurityConstants.CALLBACK_HANDLER, new ClientCallbackHandler());
    ctx.put(SecurityConstants.ENCRYPT_PROPERTIES,
        Thread.currentThread().getContextClassLoader().getResource(
        "META-INF/clientKeystore.properties"));
    ctx.put(SecurityConstants.ENCRYPT_USERNAME, "myactaskey");
    ctx.put(SecurityConstants.SIGNATURE_PROPERTIES,
        Thread.currentThread().getContextClassLoader().getResource(
        "META-INF/clientKeystore.properties"));
    ctx.put(SecurityConstants.SIGNATURE_USERNAME, "myclientkey");

    // Generate the ActAs element contents and pass to the STSClient as a string
    UsernameTokenCallbackHandler ch = new UsernameTokenCallbackHandler();
    String str = ch.getUsernameTokenString("alice","clarinet");
    ctx.put(SecurityConstants.STS_TOKEN_ACT_AS, str);

    STSClient stsClient = new STSClient(bus);
    Map<String, Object> props = stsClient.getProperties();
    props.put(SecurityConstants.USERNAME, "bob");
    props.put(SecurityConstants.CALLBACK_HANDLER, new ClientCallbackHandler());
    props.put(SecurityConstants.ENCRYPT_PROPERTIES,
        Thread.currentThread().getContextClassLoader().getResource(
        "META-INF/clientKeystore.properties"));
    props.put(SecurityConstants.ENCRYPT_USERNAME, "mystskey");
    props.put(SecurityConstants.STS_TOKEN_USERNAME, "myclientkey");
    props.put(SecurityConstants.STS_TOKEN_PROPERTIES,
        Thread.currentThread().getContextClassLoader().getResource(
        "META-INF/clientKeystore.properties"));
    props.put(SecurityConstants.STS_TOKEN_USE_CERT_FOR_KEYINFO, "true");

    ctx.put(SecurityConstants.STS_CLIENT, stsClient);
} finally {
    bus.shutdown(true);
}
proxy.sayHello();
Copy to Clipboard Toggle word wrap





更新于 2024-02-08

Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2026 Red Hat
返回顶部