Links: Table of Contents | Single HTML | Single PDF

Chapter 13. WSIT Security Features: Advanced: Topics

Table of Contents

13.1. Using Security Mechanisms
13.2. Understanding WSIT Configuration Files
13.2.1. Service-Side WSIT Configuration Files
13.2.2. Client-Side WSIT Configuration Files
13.3. Security Mechanism Configuration Options
13.4. Building custom STS
13.4.1. Handling Claims with Metro STS
13.5. Handling Token and Key Requirements at Run Time
13.6. Advanced Usages of STS in Security
13.6.1. Token Caching and Sharing
13.6.2. ActAs and Identity Delegation

13.1. Using Security Mechanisms

The security mechanism that you need to select reflects the commonly available infrastructure between your organization and another organization with which you will be communicating. The following list provides some common communication issues that need to be addressed using security mechanisms:

  • Asymmetric binding is used for message protection. This binding has two binding specific token properties: the initiator token and the recipient token. If the message pattern requires multiple messages, this binding defines that the initiator token is used for the message signature from initiator to the recipient, and for encryption from recipient to initiator. The recipient token is used for encryption from initiator to recipient, and for the message signature from recipient to initiator.

  • Some organizations have a Kerberos infrastructure, while other organizations have a PKI infrastructure (asymmetric binding). WS-Trust allows two communicating parties having different security infrastructure to communicate securely with one another. In this scenario, the client authenticates with a third party (STS) using its infrastructure. The STS returns a (digitally-signed) SAML token containing authorization and authentication information regarding the client, along with a key. The client then simply relays the token to the server and uses the STS-supplied key to ensure integrity and confidentiality of the messages sent to the server.

    Note

    Kerberos is supported in Metro since 1.1 release. Netbeans support is available for Kerberos from Metro 1.3 and Netbeans 6.5 release. Kerberos is NOT supported on AIX systems.

  • Symmetric binding is used for message protection. This binding has two binding specific token properties: encryption token and signature token. If the message pattern requires multiple messages, this binding defines that the encryption token used from initiator to recipient is also used from recipient to initiator. Similarly, the signature token used from initiator to recipient is also used from recipient to initiator.

    In some cases, the client does not have its own certificates. In this case, the client can choose a security mechanism that makes use of symmetric binding and could use a Username token as a signed supporting token for authentication with the server. The symmetric binding in this case serves the purpose of integrity and confidentiality protection.

  • In the absence of a notion of secure session, the client would have to reauthenticate with the server upon every request. In this situation, if the client is sending a Username token, the client will be asked for its username and password on each request, or, if the client is sending a certificate, the validity of the certificate has to be established with every request. This is expensive! Enable Secure Conversation to remove the requirement for re-authentication.

  • The use of the same session key (Secure Conversation) for repeated message exchanges is sometimes considered a risk. To reduce that risk, enable Require Derived Keys.

  • RSA Signatures (signatures with public-private keys) is more expensive than Symmetric Key signatures. Use the Secure Conversation option to enable Symmetric Key signatures.

  • Enabling WSS 1.1 enables an encrypted key generated by the client to be reused by the server in the response to the client. This saves the time otherwise required to create a Symmetric Key, encrypt it with the client public key (which is also an expensive RSA operation), and transmit the encrypted key in the message (it occupies markup and requires Base64 operations).

13.2. Understanding WSIT Configuration Files

When a web service or a web service client are configured for WSIT features, this information is saved in WSIT Configuration files. The following sections discuss the WSIT configuration files for the service and for the client:

13.2.1. Service-Side WSIT Configuration Files

WSIT features are configured on a web service in the following way:

  1. Right-click the web service in NetBeans IDE.

  2. Select Edit Web Service Attributes.

  3. Select and/or configure the appropriate WSIT features on the Quality Of Service Configuration tab for the web service. Many of the WSIT features are discussed in Using WSIT Security.

  4. Select OK to close the dialog.

  5. Run the web application by right-clicking the project node and selecting Run Project.

The service-side WSIT Configuration file that is used when the web service is deployed can be viewed by expanding the Web Pages | WEB-INF elements of the application in the tree, and then double-clicking the wsit-package.service.xml file to open it in the editor.

For the example application Example: Username Authentication with Symmetric Key (UA), the WSIT configuration file for the service is named wsit-org.me.calculator.CalculatorWS.xml, and looks like this:

Example 13.1. 

<?xml version="1.0" encoding="UTF-8"?>
<definitions
        xmlns="http://schemas.xmlsoap.org/wsdl/"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        name="CalculatorWSService"
        targetNamespace="http://calculator.me.org/"
        xmlns:tns="http://calculator.me.org/"
        xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
        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://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
        xmlns:sc="http://schemas.sun.com/2006/03/wss/server"
        xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy">
   <message name="add"/>
   <message name="addResponse"/>
   <portType name="CalculatorWS">
      <operation name="add">
         <input message="tns:add"/>
         <output message="tns:addResponse"/>
      </operation>
   </portType>
   <binding name="CalculatorWSPortBinding" type="tns:CalculatorWS">
      <wsp:PolicyReference URI="#CalculatorWSPortBindingPolicy"/>
      <operation name="add">
         <input>
            <wsp:PolicyReference
                    URI="#CalculatorWSPortBinding_add_Input_Policy"/>
         </input>
         <output>
            <wsp:PolicyReference
                    URI="#CalculatorWSPortBinding_add_Output_Policy"/>
         </output>
      </operation>
   </binding>
   <service name="CalculatorWSService">
      <port name="CalculatorWSPort" binding="tns:CalculatorWSPortBinding"/>
   </service>
   <wsp:Policy wsu:Id="CalculatorWSPortBindingPolicy">
      <wsp:ExactlyOne>
         <wsp:All>
            <wsaws:UsingAddressing
                    xmlns:wsaws="http://www.w3.org/2006/05/addressing/wsdl"/>
            <sp:SymmetricBinding>
               <wsp:Policy>
                  <sp:ProtectionToken>
                     <wsp:Policy>
                        <sp:X509Token sp:IncludeToken=
                           "http://schemas.xmlsoap.org/ws/2005/07/
                           securitypolicy/IncludeToken/Never">
                           <wsp:Policy>
                              <sp:WssX509V3Token10/>
                           </wsp:Policy>
                        </sp:X509Token>
                     </wsp:Policy>
                  </sp:ProtectionToken>
                  <sp:Layout>
                     <wsp:Policy>
                        <sp:Strict/>
                     </wsp:Policy>
                  </sp:Layout>
                  <sp:IncludeTimestamp/>
                  <sp:OnlySignEntireHeadersAndBody/>
                  <sp:AlgorithmSuite>
                     <wsp:Policy>
                        <sp:Basic128/>
                     </wsp:Policy>
                  </sp:AlgorithmSuite>
               </wsp:Policy>
            </sp:SymmetricBinding>
            <sp:Wss11>
               <wsp:Policy>
                  <sp:MustSupportRefKeyIdentifier/>
                  <sp:MustSupportRefIssuerSerial/>
                  <sp:MustSupportRefThumbprint/>
                  <sp:MustSupportRefEncryptedKey/>
               </wsp:Policy>
            </sp:Wss11>
            <sp:SignedSupportingTokens>
               <wsp:Policy>
                  <sp:UsernameToken
                          sp:IncludeToken="http://schemas.xmlsoap.org/
                                           ws/2005/07/securitypolicy/
                                           IncludeToken/AlwaysToRecipient">
                     <wsp:Policy>
                        <sp:WssUsernameToken10/>
                     </wsp:Policy>
                  </sp:UsernameToken>
               </wsp:Policy>
            </sp:SignedSupportingTokens>
            <sc:KeyStore wspp:visibility="private"
                         alias="xws-security-server"/>
         </wsp:All>
      </wsp:ExactlyOne>
   </wsp:Policy>
   <wsp:Policy wsu:Id="CalculatorWSPortBinding_add_Input_Policy">
      <wsp:ExactlyOne>
         <wsp:All>
            <sp:EncryptedParts>
               <sp:Body/>
            </sp:EncryptedParts>
            <sp:SignedParts>
               <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:Header Name="AckRequested"
                          Namespace="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
               <sp:Header Name="SequenceAcknowledgement"
                          Namespace="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
               <sp:Header Name="Sequence"
                          Namespace="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
            </sp:SignedParts>
         </wsp:All>
      </wsp:ExactlyOne>
   </wsp:Policy>
   <wsp:Policy wsu:Id="CalculatorWSPortBinding_add_Output_Policy">
      <wsp:ExactlyOne>
         <wsp:All>
            <sp:EncryptedParts>
               <sp:Body/>
            </sp:EncryptedParts>
            <sp:SignedParts>
               <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:Header Name="AckRequested"
                          Namespace="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
               <sp:Header Name="SequenceAcknowledgement"
                          Namespace="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
               <sp:Header Name="Sequence"
                          Namespace="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
            </sp:SignedParts>
         </wsp:All>
      </wsp:ExactlyOne>
   </wsp:Policy>
</definitions>

13.2.2. Client-Side WSIT Configuration Files

WSIT features are configured on the client in the following way:

  1. Expand the Web Service Reference node for the web service client in NetBeans IDE.

  2. Select Edit Web Service Attributes.

  3. Select and/or configure the appropriate WSIT features on the Quality Of Service tab for the web service client. Many of the WSIT features are discussed in Using WSIT Security.

  4. Select OK to close the dialog.

  5. Run the web service client by right-clicking the project node and selecting Run Project.

The WSIT Configuration information can be viewed by expanding Source Packages | META-INF in NetBeans IDE for the client project. This directory contains two files: serviceService.xml and wsit-client.xml.

The serviceService.xml file is an XML file that must conform to the WSDL specification. The WSIT configuration is written to this file. For the example application Example: Username Authentication with Symmetric Key (UA), the WSIT configuration file for the client is named CalculatorWSService.xml, and looks like this:

Example 13.2. 

<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI at http://jax-ws.java.net. RI's version
                is JAX-WS RI 2.1.2_01-hudson-189-. --><!-- Generated by JAX-WS
                RI at http://jax-ws.java.net. RI's version is JAX-WS RI
                2.1.2_01-hudson-189-. -->
<definitions
        xmlns:wsu=
             "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
             utility-1.0.xsd"
        xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:tns="http://calculator.me.org/"
        mlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns="http://schemas.xmlsoap.org/wsdl/"
        targetNamespace="http://calculator.me.org/"
        name="CalculatorWSService"
        xmlns:sc="http://schemas.sun.com/2006/03/wss/client"
        xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"
        xmlns:tc="http://schemas.sun.com/ws/2006/05/trust/client">
   
   <wsp:UsingPolicy></wsp:UsingPolicy>
   <types>
      <xsd:schema>
         <xsd:import namespace="http://calculator.me.org/"
                     schemaLocation="http://localhost:8080/CalculatorApplication/
                CalculatorWSService?xsd=1">
         </xsd:import>
      </xsd:schema>
   </types>
   <message name="add">
      <part name="parameters" element="tns:add"></part>
   </message>
   <message name="addResponse">
      <part name="parameters" element="tns:addResponse"></part>
   </message>
   <portType name="CalculatorWS">
      <operation name="add">
         <input message="tns:add"></input>
         <output message="tns:addResponse"></output>
      </operation>
   </portType>
   <binding name="CalculatorWSPortBinding" type="tns:CalculatorWS">
      <wsp:PolicyReference URI="#CalculatorWSPortBindingPolicy"/>
      <soap:binding transport="http://schemas.xmlsoap.org/
                soap/http" style="document"></soap:binding>
      <operation name="add">
         <soap:operation soapAction=""></soap:operation>
         <input>
            <soap:body use="literal"></soap:body>
         </input>
         <output>
            <soap:body use="literal"></soap:body>
         </output>
      </operation>
   </binding>
   <service name="CalculatorWSService">
      <port name="CalculatorWSPort" binding="tns:CalculatorWSPortBinding">
         <soap:address location="http://localhost:8080/
                CalculatorApplication/CalculatorWSService">
         </soap:address>
      </port>
   </service>
   <wsp:Policy wsu:Id="CalculatorWSPortBindingPolicy">
      <wsp:ExactlyOne>
         <wsp:All>
            <sc:KeyStore
                  wspp:visibility="private"
                  location="c:\Sun\glassfish\domains\domain1\config\keystore.jks"
                  storepass="changeit" alias="xws-security-client"/>
            <sc:TrustStore
                    wspp:visibility="private"
                    location="c:\Sun\glassfish\domains\domain1\config\cacerts.jks"
                    storepass="changeit"
                    peeralias="xws-security-server"/>
            <tc:PreconfiguredSTS wspp:visibility="private"/>
            <sc:CallbackHandlerConfiguration wspp:visibility="private">
               <sc:CallbackHandler default="wsitUser"
                                   name="usernameHandler"/>
               <sc:CallbackHandler default="changeit"
                                   name="passwordHandler"/>
            </sc:CallbackHandlerConfiguration>
         </wsp:All>
      </wsp:ExactlyOne>
   </wsp:Policy>
</definitions>

The wsit-client.xml file imports the serviceService.xml file. For the example shown about, the wsit-client.xml file looks like this:

Example 13.3. 

<?xml version="1.0" encoding="UTF-8"?>
<definitions
        xmlns="http://schemas.xmlsoap.org/wsdl/"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        name="mainclientconfig">
    <import location="CalculatorWSService.xml"
            namespace="http://calculator.me.org/"/>
</definitions>

When running the client, these two files will need to be in the classpath, either at the classpath root (i.e., build/classes) or in a META-INF directory under the classpath root.

13.3. Security Mechanism Configuration Options

The following fields shown in Security Mechanism Configuration Options are used to configure different security policies. Not every option is available for every mechanism, but many of the policies include the same configuration options, so they are grouped here for the purposes of defining them in one central location.

Table 13.1. Security Mechanism Configuration Options

Option

Description

Algorithm Suite

This attribute specifies the algorithm suite required for performing cryptographic operations with symmetric or asymmetric key-based security tokens. An algorithm suite specifies actual algorithms and allowed key lengths. A mechanism alternative will define what algorithms are used and how they are used. The value of this attribute is typically referenced by a security binding and is used to specify the algorithms used for all cryptographic operations performed under the security binding. The default value is Basic 128 bit.

Some of the algorithm suite settings require that Unlimited StrengthEncryption be configured in the Java Runtime Environment (JRE), particularly the algorithm suites that use 256 bit encryption. Instructions for downloading and configuring unlimited strength encryption can be found at the following URLS:

http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136007.html

http://java.sun.com/javase/downloads/index_jdk5.jsp#docs

Read the OASIS specification WS-Security Policy section on Security Binding Properties for more description of the components for each of these algorithm suites. A link to this document can be found at http://wsit.java.net/.

Encrypt Before Signing

If selected, specifies that the order of message protection is to encrypt the SOAP content, then sign the entire SOAP body. Encryption key and signing key must be derived from the same source key.

If not selected, the default behavior is Sign Before Encrypt.

Encrypt Signature

Specifies whether the signature must be encrypted. If selected, the primary signature must be encrypted and any signature confirmation elements must also be encrypted. If not selected (the default), the primary signature must not be encrypted and any signature confirmation elements must not be encrypted.

Enable EPR Identity

This feature enables the service to produce its public key in the wsdl.Clients who wants to consume the service can use this public key to encrypt messages and hence they do not need to specify the peerAlias in their configuration, but still TrustStore configuration is needed to validate the certificate. Current Netbeans versions do not support the UI to configure this.So for a detailed description about this feature and to know how to configure this , please visit the blog: http://blogs.sun.com/SureshMandalapu/entry/support_of_endpoint_references_with

Securing only some of the WS operations

With latest metro we can secure only required operations in a service unlike in the older version where we have to secure either all or no operations.This means the security is at binding level , but not at operation level.But with latest metro , the security policies can be specified for individual operations,thus we can secure only required operations in a service

For a detailed description and how to configure this , please go through the blog: http://blogs.sun.com/SureshMandalapu/entry/support_of_binding_assertions_at

Establish Secure Session (Secure Conversation)

Secure Conversation enables a consumer and provider to establish a shared security context when a multiple-message-exchange sequence is first initiated. Subsequent messages use (possibly derived) session keys that increase the overall security while reducing the security processing overhead for each message.

In the absence of a notion of secure session, the client would have to reauthenticate with the server upon every request. In this situation, if the client is sending a Username token, it has to authenticate on every request, or, if the client is sending a certificate, the validity of the certificate has to be established on every request. This is expensive. Enable Secure Conversation to get over this requirement for re-authentication.

When this option and Require Derived Keys are both enabled, a derived key will be used. If not, the original session key will be used.

Note on Secure Conversation with Reliable Message Delivery: Reliable Messaging can be used independently of the security mechanisms; however, when Reliable Messaging (RM) is used with a security mechanism, it requires the use of Secure Conversation, which will be automatically configured for a security mechanism when Reliable Messaging is selected before the security mechanism is selected. If Secure Conversation is selected for a security mechanism and the Reliable Messaging option was not selected before the security mechanism was specified, Reliable Messaging will need to be manually selected in order for Secure Conversation to work. Reliable messaging, as well as the Advanced configuration options and Deliver Messages in Exact Order feature, is discussed in Using Reliable Messaging.

Issuer Address

This optional element specifies the address of the issuer (STS) that will accept the security token that is presented in the message. This element's type is an endpoint reference. An STS contains a set of interfaces to be used for the issuance, exchange, and validation of security tokens. An example that creates and uses an STS can be found at Example: STS Issued Token (STS).

For example, a Metro STS Issuer Address might be:

http://localhost:8080/jaxws-sts/sts

An examle WCF STS Issuer Address might be:

http://131.107.72.15/ \
Security_Federation_SecurityTokenService_Indigo/ \
Symmetric.svc/ \
Scenario_5_IssuedTokenForCertificate_MutualCertificate11

Issuer Metadata Address

Specifies the address (URLs) from which to retrieve the issuer metadata. For example, a Metro STS Issuer Metadata Address might be:

http://localhost:8080/jaxws-sts/sts

For a WCF STS the Issuer Metadata Address might be:

http://131.107.72.15/ \
Security_Federation_SecurityTokenService_Indigo/ \
Symmetric.svc

For more information, read Configuring A Secure Token Service (STS).

Key Type

Applicable for Issued Token mechanisms only. The type of key the service provider desires. The choices are public key or symmetric key. Symmetric key cryptography relies on a shared secret and is usually faster than public key cryptography. Public key cryptography relies on a key that is made public to all and is primarily used for encryption but can be used for verifying signatures.

Key Size

Applicable for Issued Token mechanisms only. The size of the symmetric key requested, specified in number of bits. This is a request, and, as such, the requested security token is not obligated to use the requested key size, nor is the STS obligated to issue a token with the same key size. That said, the recipient should try to use a key at least as strong as the specified value if possible. The information is provided as an indication of the desired strength of the security. Valid choices include 128, 192, and 256.

Require Client Certificate

Select this option to require that a client certificate be provided to the server for verification.

If you are using a security mechanism with SSL, a client certificate will be required by the server both during its initial handshake and again during verification.

Require Derived Keys

Require Derived Keys for:

Issued Token, Secure Session, X509 Token

A derived key is a cryptographic key created from a password or other user data. Derived keys allow applications to create session keys as needed, eliminating the need to store a particular key. The use of the same session key (for example, when using Secure Conversation) for repeated message exchanges is sometimes considered a risk. To reduce that risk, enable Require Derived Keys.

Require Signature Confirmation

When the WSS Version is 1.1, select this option to reduce the risk of attacks because signature confirmation indicates that the responder has processed the signature in the request. For more information, read section 8.5, Signature Confirmation, of the Web Services Security: SOAP Message Security 1.1 specification at http://www.oasis-open.org/committees/download.php/16790/wss-v1.1-spec-os-SOAPMessageSecurity.pdf.

SAML Version

Specifies which version of the SAML token should be used. The SAML Version is something the CallbackHandler has to verify, not the security runtime. SAML tokens are defined in WSS: SAML Token Profile documents, available from http://www.oasis-open.org/specs/index.php.

For an example that uses SAML Callbacks, refer to Example: SAML Authorization over SSL (SA).

Security Header Layout

Specifies which layout rules to apply when adding items to the security header. The options are:

  • Strict: Items are added to the security header following the general principle of "declare before using".

  • Lax: Items are added to the security header in any order that conforms to WSS: SOAP Message Security. However, WSIT follows Strict even when Lax is selected.

  • Lax (Timestamp First or Last): The same as for Lax, except that the first or last item in the security header must be a wsse:Timestamp.

Examples of the layout rules are described in the OASIS WS-SecurityPolicy specification, a link to which can be found at http://wsit.java.net/.

Supporting Token

Specifies the type of supporting token to be used. Supporting Tokens are included in the security header and may sign and/or encrypt additional message parts. Valid options for supporting tokens include X.509 tokens, Username tokens, SAML tokens, or an Issued Token from an STS.

For more information on these options, read Supporting Token Options.

Token Type

The type of SAML token the service provider requires, for example, urn:oasis:names:tc:SAML1.0:assertion.Choices are 1.0, 1.1, or 2.0.

WSS Version

Specifies which version of the Web Services Security specification should be followed, 1.0 or 1.1. These specifications can be viewed from http://www.oasis-open.org/specs/index.php.

Enabling WSS 1.1 enables an encrypted key generated by the client to be reused by the Server in the response to the client. This saves the time otherwise required to create a Symmetric Key during the course of response, encrypt it with the client public key (which is also an expensive RSA operation), and transmit the encrypted key in the message (it occupies markup and requires Base64 operations). Enabling WSS 1.1 also enables encrypted headers.


13.4. Building custom STS

It is described in section 11.8 (To Create a Third-Party STS) how to build a WS-Trust Security Token Service (STS). Thus created STS can be configured to authenticate the client with username/passwords, X.509 certificates, etc. and to issue either SAML 1.0 or SAML 2.0 assertions. By default the issued SAML tokens will contain an SAML AttributeStatement with the user authenticated identity to the STS and a dummy attribute.

In practice, users may have different identities when using different web services. For authorization or privacy purposes, different user identity and/or user attributes (e.g. role or authorization code) are required to be included in the issued SAML assertion for a service.

WSIT provides an interface com.sun.xml.ws.api.security.trust.STSAttributeProvider for use in plugging user identity/attribute mappings into an STS. The implementation class of the STSAttributeProvider is exposed to the system with the standard ServiceFinder mechanism, i.e. using a file META-INF/services/com.sun.xml.ws.api.security.trust.STSAttributeProvider in the classpath. The file contains the names of STSAttributeProvider implementation classes, one per line. The mapped user identity/attributes will be picked up when creating SAML assertions.

Here are the steps for creating a custom STSAttributeProvider and plugging it into an STS created from NetBeans:

  1. Use NetBeans to To Create a Third-Party STS.

  2. Create an MySTSAttributeProvider implementation class in the same package as the STS implementation class which extends the BaseSTSImpl.

  3. Create a directory META-INF/services in the src/java directory.

  4. Create a file with name com.sun.xml.ws.api.security.trust.STSAttributeProvider with content the path to the class MySTSAttributeProvider (e.g. org.me.sts.MySTSAttributeProvider). Then place this file in the src/java/META-INF/services directory.

  5. Run the NetBeans STS project. Your STS will now use your custom attribute provider in creating the SAML assertions.

As a reference, here is a sample STSAttributeProvider.

13.4.1. Handling Claims with Metro STS

In WS-SecurityPolicy, an IssuedToken policy assertion may carry an optional wst:Claims element, to specify the actual claims required to access the service. Here is an example of IssuedToken policy assertions with Claims:

Example 13.4. 

<sp:IssuedToken sp:IncludeToken="...">
   <Issuer xmlns="...">
      <Address xmlns="http://www.w3.org/2005/08/addressing">...</Address>
   </Issuer>
   <sp:RequestSecurityTokenTemplate
           xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
      <t:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</t:TokenType>
      <t:KeyType>http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey
      </t:KeyType>
      <t:KeySize>256</t:KeySize>
      <t:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
                xmlns:ic="http://schemas.xmlsoap.org/ws/2005/05/identity">
         <ic:ClaimType
                 Uri="http://.../ws/2005/05/identity/claims/givenname"/>
         <ic:ClaimType Uri="http://.../ws/2005/05/identity/claims/surname"
                       Optional="true"/>
      </wst:Claims>
   </sp:RequestSecurityTokenTemplate>
</sp:IssuedToken>

With Oasis standard versions of WS-SecurityPolicy 1.2 and WS-Trust 1.3, syntax is different for Claims, where it is defined as a top level sub-element of IssuedToken, in stead of a sub-element of RequestSecurityTokenTemplate:

Example 13.5. 

<sp:IssuedToken sp:IncludeToken="...">
   <Issuer xmlns="...">
      <Address xmlns="http://www.w3.org/2005/08/addressing">...</Address>
   </Issuer>
   <t:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
             xmlns:ic="http://schemas.xmlsoap.org/ws/2005/05/identity">
      <ic:ClaimType Uri="http://.../ws/2005/05/identity/claims/givenname"/>
      <ic:ClaimType Uri="http://.../ws/2005/05/identity/claims/surname"
                    Optional="true"/>
   </wst:Claims>
   <sp:RequestSecurityTokenTemplate
           xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
      <t:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</t:TokenType>
      <t:KeyType>http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey
      </t:KeyType>
      <t:KeySize>256</t:KeySize>
   </sp:RequestSecurityTokenTemplate>
</sp:IssuedToken>

On the client side, the Claims, together with all the elements in the RequestSecurityTokenTemplate, is copied into the request message RST to the STS.

With Metro based STS, the Claims will then be available in the STSAttributeProvider, for use to build the user attributes to be included in the issued SAML assertion.

In your implementation of the method, getClaimedAttributes(Subject subject, String appliesTo, String tokenType, Claims claims), one may parse the Claims to obtain the ClaimTypes with the following codes:

Example 13.6. 

String dialect = claims.getDialect();
List<Object> claimTypes = claims.getAny();
for (Object claimType : claimsTypes){
    Element ctElement = (Element) claimType;
    // parsing ctElement according to the dialect to get claim types
    ...
}

Once you parse the Claims, you may create the attributes accordingly. The attributes returned from the STSAttributeProvider is available in the STSTokenProvider through:

Example 13.7. 

(Map<QName, List<String>>) ctx.getOtherProperties().get(IssuedTokenContext.CLAIMED_ATTRUBUTES);


for you to build into your issued SAML assertions.

See also Handling Token and Key Requirements at Run Time for how to inject Claims on the client side at run time.

13.5. Handling Token and Key Requirements at Run Time

In the general model for using STS issued tokens to securing Web services, a service side IssuedToken policy assertion is used to specify the STS information (STS endpoint, STS MEX endpoint, etc) and the token requirements (token type, key type, claims, etc). Alternatively, a client side PreConfiguredSTS assertion can be used to specify the local STS. Only one STS can be specified in PreconfiguredSTS. In this way, the process to go to STS to obtain the issued toke and subsequently use it with the messages to the service was handled by Metro transparently to the users.

Now with Metro 2.0, one may also inject STS information and issued token requirements programmatically at run time on the client side. This This gives the users more control of the its identity and security information to be used to access a service, hence open up for building more interesting and important applications with Metro.

General steps for managing run time configuration:

  1. Use existing STSIssuedTokenConfiguration for run-time configuration, e.g.

    Example 13.8. 

    DefaultSTSIssuedTokenConfiguration config = new DefaultSTSIssuedTokenConfiguration();
    Claims claims = ...
    config.setClaims(claims);


  2. Use Web Service Feature to inject STSIssuedTokenConfiguration into the system:

    Example 13.9. 

    STSIssuedTokenFeature feature = new STSIssuedTokenFeature(config);


  3. STSIssuedTokenFeature is used when creating port from the Service:

    Example 13.10. 

    CalculatorWS port = service.getCalculatorWSPort(new WebServiceFeature[]{feature});


  4. The entries in IssuedToken policy assertion in services WSDL is available through

    Example 13.11. 

    configure.getOtherOptions().get(STSIssuedTokenConfiguration.ISSUED_TOKEN);


    This allows the users to select STS at run time according to the service requirements.

While it is more or less straight forward with TokenType, KeyType, etc., it requires extra effort for managing Claims requirement at run time:

  1. Claims are defined as an extensible element in the WS-SecurityPolicy spec:

    Example 13.12. 

    <wst:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
                xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
    </wst:Claims>


  2. It is up to the applications and profiles of WS-Trust to define the content of the Claims. So you need to implement com.sun.xml.ws.api.security.trust.Claims to manage claims in your environment. Here is a sample for managing claim types of the following form:

    Example 13.13. 

    <wst:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
                xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512"
                xmlns:ic="http://schemas.xmlsoap.org/ws/2005/05/identity">
       <ic:ClaimType
          Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality"/>
       <ic:ClaimType
          Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"/>
    </wst:Claims>


  3. Make run time requirement for claim types on the client side:

    Example 13.14. 

    DefaultSTSIssuedTokenConfiguration config = new 
            DefaultSTSIssuedTokenConfiguration();
    STSIssuedTokenFeature feature = new STSIssuedTokenFeature(config);
    org.me.calculator.client.CalculatorWS port = service
            .getCalculatorWSPort(new WebServiceFeature[]{feature});
    
    int i = Integer.parseInt(request.getParameter("value1"));
    int j = Integer.parseInt(request.getParameter("value2"));
    
    config.setTokenType("urn:oasis:names:tc:SAML:1.0:assertion");
    MyClaims claims = new MyClaims();
    claims.addClaimType(MyClaims.ROLE);
    config.setClaims(claims);
    int result = port.add(i, j)


In general, you may need to supply your own STSIssuedTokenConfiguration in following cases:

  1. The client has to go through multiple STS in a trust chain across security domains to access the service.

  2. The client needs to select the STS and/or to provide token and key parameters to the STS at run time, according to which service it tries to access and the requirement from the service.

To create a custom configuration class which extends STSIssuedTokenConfiguration:

  1. You may get the targeted service endpoint at run time through

    Example 13.15. 

    getOtherOptions().get(STSIssuedTokenCOnfiguration.APPLIES_TO);


  2. Similarly, you may get an instance of STSIssuedTokenConfiguration, which captures entries from the IssuedToken policy assertion for the targeted service, through

    Example 13.16. 

    getOtherOptions().get(STSIssuedTokenCOnfiguration.ISSUED_TOKEN);


  3. The entries in the IssuedToken policy and in the client side PreConfiguredSTS take high priorities which cannot be override at run time.

  4. Different run time entries should be supplied for different services.

13.6. Advanced Usages of STS in Security

The following sections discuss some features for advanced usages of STS in securing Web services with:

13.6.1. Token Caching and Sharing

Here is a description of how this is supported in Metro:

  1. The services to be accessed with the same token must share the same certificate.

  2. Only issued tokens from the same STS are shared.

  3. Caching and sharing issued tokens can be enabled for each service instance by configuration

To enable this for a service proxy, you need to add attribute shareToken="true" in the wsit-client.xml or the file referenced by it for the proxy:

Example 13.17. 

<t:PreConfiguredSTS
     xmlns:t="http://schemas.sun.com/ws/2006/05/trust/client"
     shareToken="true">
</t:PreConfiguredSTS>


To illustrate the usage, you may find a stand alone sample here. This sample contains 4 parts for client, STS, Service, and Service1. Each service is configured to use the STS issued token to access. On the client side, the client instances for Service and Service1 are configured to be in the circle to share the issued tokens from the STS. The client calls Service first, then Service1. You will see that the client goes to the STS to get the token to access Service, and then to call Service1 without going to the STS but use the token obtained in calling Service.

Here is a description on how to managing the lifetime and renewing of the issued tokens:

  1. The client can request for the life time of an issued token through configuration with a subelement LifeTime of PreConfiguredSTS:

    Example 13.18. 

    <t:PreConfiguredSTS
          xmlns:t="http://schemas.sun.com/ws/2006/05/trust/client"
          shareToken="true">
    
        <t:LifeTime>3600</LifeTime>
    </t:PreConfiguredSTS>


    or programmatically with STSIssuedTokenConfiguration:

    Example 13.19. 

    config.getOtherOptions().put(STSIssuedTokenConfiguration.LIFE_TIME, Integer.valueOf(3600));


    The value is used to construct the Lifetime element in the RST to the STS:

    Example 13.20. 

    <trust:Lifetime>
        <wsu:Created xmlns:wsu="...">2007-10-31T18:39:23.548Z</wsu:Created>
        <wsu:Expires xmlns:wsu="...">2007-11-01T02:39:23.548Z</wsu:Expires>
    </trust:Lifetime>


  2. By default, an exception is thrown if the token cached to be used on the client side is expired.

  3. One can enable to automatically request for a new token for an expired token by configuration with attribute renewExpiredToken in PreConfiguredSTS:

    Example 13.21. 

    <t:PreConfiguredSTS
          xmlns:t="http://schemas.sun.com/ws/2006/05/trust/client"
          shareToken="true"
          renewExpiredToken="true">
    
        <t:LifeTime>3600</LifeTime>
    </t:PreConfiguredSTS>


    or programmatically with STSIssuedTokenConfiguration:

    Example 13.22. 

    config.getOtherOptions()
            .put(STSIssuedTokenConfiguration.RENEW_EXPIRED_TOKEN, "true");


13.6.2. ActAs and Identity Delegation

We provide support for ActAs introduced in WS-Truts 1.4 in Metro 2.0

Figure 13.1. ActAs and Identity Delegation

ActAs and Identity Delegation

This feature is better illustrated by the sample here

  1. The Client send a request to the STS. The request message carries the username/password of the user and is secured with the STS certificate.

  2. The STS issues an SAML assertion containing the username (e.g. Alice) as subject id and role attribute (see src\common\SampleSTSAttributeProvider). Then it send a response message with the issued token to the Client.

  3. The client send a request to the Service. The message carries the SAML assertion from the previous step for authentication and secured with the Service certificate.

  4. The Service send a request to the STS. The message contains the username/password (bob/bob) of the Service, the SAML assertion received from the user in the previous step in an ActAs element in the body (RST), and is secure with the STS certificate (see src\fs\ simple\server\FSImpl.java. The ActAs token is injected into the request using the STSIssuedTokenFeture). It means to ask for an issued token with it the Service can access the Service 1, acting as the user.

  5. The STS issues an (act as) SAML assertion which contains the Service id (bob) in the Subject, and attribute ActAs with the user name (e.g. Alice), and role attribute for the user (see src\common\SampleSTSAttributeProvider). It then send a response message with the issued token to the Service.

  6. The Service sand a request to the Service 1. The message carries the act as SAML from the previous step and is secured with the Service 1 certificate. The Service 1 check the act as SAML assertion (see src\common\SampleSamlValidator.java) and understands it is the Service who made the request act as the user.

  7. The Service 1 send a response to the Service.

  8. The Service sends a response to the Client.

Common issues and solutions:

  1. When a custom SAML assertion validator is used, the SAML assertion is not available in the Subject.

    In this case, you need to use the extended version com.sun.xml.wss.impl.callback.SamlValidator and to add explicitly the DOM based saml assertion to the public credentials of the Subject in your implementation of the method

    Example 13.23. 

    validate(XMLStreamReader assertion, Map runtimeProps,
             Subject clientSubject)
    and
    validate(Element assertion, Map runtimeProps, Subject clientSubject)


    in the interface.

  2. ActAs is not called in your custom STSAttributeProvider:

    You need to use the WSTrustContractImpl for your STS as specified in the STSConfiguration in the sts wsdl:

    Example 13.24. 

    <tc:STSConfiguration
            xmlns:tc="http://schemas.sun.com/ws/2006/05/trust/server"
            sencryptIssuedKey="true" encryptIssuedToken="false">
       <tc:LifeTime>36000</tc:LifeTime>
       <tc:Contract>com.sun.xml.ws.security.trust.impl.WSTrustContractImpl
       </tc:Contract>
       ...
    </tc:STSConfiguration>


    If you use Netbenas to create STS, IssueSAMLTokenContractImpl is set by default. You need to change it to WSTrustContractImpl for "ActAs" support.