Sun Java System Access Manager 7.1 Federation and SAML Administration Guide

Chapter 5 Liberty Alliance Project Web Services Framework

Sun Java™ System Access Manager implements the Liberty Identity Web Services Framework (Liberty ID-WSF) which defines a web services stack that can be used to support the Liberty Alliance Project business model. These web services leverage the Liberty ID-FF for principal authentication, federation, and privacy protections. This chapter covers the following topics:

Web Services

Web services are distributed applications developed using open technologies such as eXtensible Markup Language (XML), SOAP, and HyperText Transfer Protocol (HTTP). Enterprises use these technologies as a mechanism for allowing their applications to cross network boundaries and communicate with those of their partners, customers and suppliers. Access Manager implements the Liberty ID-WSF which is designed to operate in concert with a federated identity framework, such as the Liberty Identity Federation Framework (Liberty ID-FF). Previous releases of Access Manager implemented the Liberty ID-WSF version 1.0. This current release of Access Manager 7.1 extends the implementation to include version 1.1. Access Manager includes the following Liberty ID-WSF web services:

Authentication Web Service

The Authentication Web Service adds authentication functionality to the SOAP binding. It provides authentication to a WSC, allowing the WSC to obtain security tokens for further interactions with other services at the same provider. These other services may include a discovery service or single sign-on service. Upon successful authentication, the final Simple Authentication and Security Layer (SASL) response contains the resource offering for the Discovery Service. For more information, see Chapter 6, Authentication Web Service.

Caution – Caution –

Do not confuse the Liberty-based Authentication Web Service with the proprietary Access Manager Authentication Service discussed in the Sun Java System Access Manager 7.1 Technical Overview.

Liberty Personal Profile Service

The Liberty Personal Profile Service is a data service that supports storing and modifying a principal's identity attributes. It maps attributes defined in a user's personal profile to LDAP attributes in a data store. These identity attributes might include the user's first name, last name, home address, or emergency contact information. The Liberty Personal Profile Service is queried or updated by a WSC acting on behalf of the principal. For more information, see Chapter 7, Data Services.

Discovery Service

The Discovery Service is a framework for describing and discovering identity web services. It allows a requesting entity, such as a service provider, to dynamically determine a principal's registered web services provider (WSP), such as an attribute provider. Typically, a service provider queries the Discovery Service, which responds by providing a resource offering that describes the requested WSP. (A resource offering defines associations between a piece of identity data and the service instance that provides access to the data.) The implementation of the Discovery Service includes Java and web-based interfaces. The service is bootstrapped using Liberty ID-FF single sign-on or the Liberty ID-WSF Authentication Web Service. For more information, see Chapter 8, Discovery Service.

Note –

By definition, a discoverable service is assigned a service type URI, allowing the service to be registered in Discovery Service instances. The service type URI is typically defined in the Web Service Definition Language (WSDL) file that defines the service.

SOAP Binding Service

The SOAP Binding Service is the method of transport used to convey identity data between web services. It includes a set of Java APIs used by the developer of a Liberty-enabled identity service. The APIs are used to send and receive identity-based messages using SOAP, an XML-based messaging protocol. The service invokes the correct request handler class (specified by a service endpoint) to handle the messages. For more information, see Chapter 9, SOAP Binding Service.

Liberty ID-WSF Architecture in Access Manager

The Liberty ID-WSF defines an architecture in which SOAP over HTTP(S) is used as the transport layer protocol. As well, custom web services can be plugged into it. All web services in Access Manager (whether proprietary or custom) are front-ended by a servlet endpoint called the SOAPReceiver. The SOAPReceiver validates digital signatures or encryptions from incoming SOAP request messages and authenticates the remote web services client. The following diagram shows the high level architecture of the Access Manager implementation of the Liberty ID-WSF.

Illustration of high-level architecture of Access Manager implementation
of Liberty ID-WSF.

In the high-level process between a WSC and an Access Manager WSP, a user requests a specific service on a WSC which passes the request to Access Manager. The request is received by the SOAPReceiver which, in turn, passes it to the corresponding WSP (for example, the Liberty Personal Profile Service or a custom web service). More detailed information can be found in SOAP Binding Process.

Web Services and Security

Access Manager defines a variety of security mechanisms for protecting web services. It includes security mechanisms from both the Liberty ID-WSF Security Mechanisms Specification and the WS-Security version 1.x specifications. The SOAP Binding Service is where security is configured. It can be configured globally for all the services hosted by Access Manager to limit the accepted security mechanisms or, each web service can define it's own security mechanisms for more fine-grained security. The primary advantage of deploying the web services using Access Manager is that web services security is handled by the Access Manager allowing application developers to concentrate on the business logic of their web service. There are blueprints available that present solutions for developing secure web services by enabling application-level or message-level security. They can be found on the open development web site for the Java BluePrints Project.

Note –

These blueprints require that Access Manager be deployed in an instance of Application Server 9 (which is not a supported container on Sun Java Enterprise System 5).

Developing New Web Services

Any web service that is plugged into the Access Manager Liberty ID-WSF framework must register a key, and an implementation of the interface, with the SOAP Binding Service. (For example, the Liberty Personal Profile Service is registered with the key idpp, and the class com.sun.identity.liberty. ws.soapbinding.PPRequestHandler.) The Key value becomes part of the URL for the web service's endpoint (as in protocol://host:port/deploymenturi/Liberty/key). The implemented class allows the web service to retrieve the request (containing the authenticated principal and the authenticated security mechanism along with the entire SOAP message). The web service processes the request and generates a response. This section contains the process you would use to add a new Liberty ID-WSF web service to the Access Manager framework. Instructions for some of these steps are beyond the scope of this guide. The process has been divided into two tasks:

ProcedureTo Host a Custom Service

Before You Begin

The XML Schema Definition (XSD) file written to define the new service is the starting point for developing the service's server-side code. More information can be found in Schema Files and Service Definition Documents.

  1. Write an XML service schema for the new web service and Java classes to parse and process the XML messages.

    The following sample schema defines a stock quote web service. The QuoteRequest and QuoteResponse elements define the parameters for the request and response that are inserted in the SOAP Body of the request and response, respectively. You will need to have and to parse and process the XML messages.

    <?xml version="1.0" encoding="UTF-8" ?> 
    <xs:schema xmlns:xs=""
             This is a sample stock ticker web service protocol
      <xs:element name="QuoteRequest" type="QuoteRequestType"/>
      <xs:complexType name="QuoteRequestType">
            <xs:element name = "ResourceID" type="xs:string" minOccurs="0"/>
            <xs:element name = "Symbol" type="xs:string" minOccours="1"/>
      <xs:complexType name="PriceType">
              <xs:element name="Last" type="xs:integer"/>
              <xs:element name="Open" type="xs:integer"/>
              <xs:element name="DayRange" type="xs:string"/>
              <xs:element name="Change" type="xs:string"/>
              <xs:element name="PrevClose" type="xs:integer"/>
      <xs:element name="QuoteResponse" type="QuoteResponseType"/>
      <xs:complexType name="QuoteResponseType">
            <xs:element name="Symbol" type="xs:string"/>
            <xs:element name="Time" type="xs:dateTime"/>
            <xs:element name="Delay" type="xs:dateTime" minOccurs="0"/>
            <xs:element name="Price" type="PriceType"/>
            <xs:element name="Volume" type="xs:integer"/>
  2. Provide an implementation for one of the following interfaces based on the type of web service being developed:

    • for developing and deploying a general web service.

      See SOAP Binding Service Package.

    • for developing and deploying an identity data service type web service based on the Liberty Alliance Project Identity Service Interface Specifications (Liberty ID-SIS).

      See Package.

    In Access Manager, each web service must implement one of these interfaces to accept incoming message requests and return outgoing message responses. The following sample implements the interface for the stock quote web service. is the API used to construct requests and responses.

    public class StockTickerService implements RequestHandler {
             //implement business logic
             public Message processRequest(Message msg) throws 
                           SOAPFaultException, Exception {
                    SSOToken token = (SSOToken)msg.getToken();
                    List responseBody = processSOAPBody(msg.getBodies());
                    Message response = new Message();
                    return response;
              //more business logic
  3. Compile the Java source code.

    Be sure to include /AccessManager-base/SUNWam/lib/am_services.jar in your classpath.

  4. Add the previously created classes to the web container classpath and restart the web container.

  5. Login to the Access Manager console as the top level administrator.

    By default, amadmin.

  6. Click the Web Services tab.

  7. Under Web Services, click the SOAP Binding Service tab to register the new implementation with the SOAP Binding Service.

    Screen capture of SOAP Binding Service attributes
  8. Click New under the Request Handler List global attribute.

  9. Enter a name for the implementation in the Key field.

    This value will be used as part of the service endpoint URL for the web service. For example, if the value is stock, the endpoint URL to access the stock quote web service will be:

  10. Enter the name of the implementation class previously created in the Class field.

  11. (Optional) Enter a SOAP Action in the SOAP Action field.

  12. Click Save to save the configuration.

    The request handler will be displayed under the Request Handler List.

  13. Click on the Access Control tab to begin the process of publishing the web service to the Discovery Service.

    The Discovery Service is a registry of web services. It matches the properties in a request with the properties in its registry and returns the appropriate service location. See Chapter 8, Discovery Service.

  14. Select the name of the realm to which you want to add the web service.

  15. Select Services to access the realm's services.

  16. Click Discovery Service.

    If the Discovery Service has not yet been added, do the following.

    1. Click Add.

      A list of available services is displayed.

    2. Select Discovery Service and click Next to add the service.

      The list of added services is displayed including the Discovery Service.

  17. Click Add to create a new resource offering.

    Screen capture of New Resource Offerings attributes.
  18. (Optional) Enter a description of the resource offering in the Description field.

  19. Type a URI for the value of the Service Type attribute.

    This URI defines the type of service. It is recommended that the value of this attribute be the targetNamespace URI defined in the abstract WSDL description for the service. An example of a valid URI for the sample service is urn:com:sun:liberty:sample:stockticker.

  20. Type a URI for the value of the Provider ID attribute.

    The value of this attribute contains the URI of the provider of the service instance. This information is useful for resolving trust metadata needed to invoke the service instance. A single physical provider may have multiple provider IDs.

    Note –

    The provider represented by the URI in the Provider ID attribute must also have an entry in the ResourceIDMapper attribute. For more information, see Classes For ResourceIDMapper Plug-in.

  21. Click New Description to define the Service Description.

    For each resource offering, at least one service description must be created.

    1. Select the values for the Security Mechanism ID attribute to define how a web service client can authenticate to a web service provider.

      This field lists the security mechanisms that the service instance supports. Select the security mechanisms that you want to add and click Add. To prioritize the list, select the mechanism and click Move Up or Move Down.

    2. Type a value for the End Point URL.

      This value is the URL to access the new web service. For this example, it should be:

    3. (Optional) Type a value for the SOAP Action.

      This value is the equivalent of the wsdlsoap:soapAction attribute of the wsdlsoap:operation element in the service's concrete WSDL-based description.

    4. Click OK to complete the configuration.

  22. Check the Options box if there are no options or add a URI to specify options for the resource offering.

    This field lists the options that are available for the resource offering. Options provide hints to a potential requestor about the availability of certain data or operations to a particular offering. The set of possible URIs are defined by the service type, not the Discovery Service. If no option is specified, the service instance does not display any available options. For a standard set of options, see the Liberty ID-SIS Personal Profile Service Specification.

  23. Select a directive for the resource offering.

    Directives are special entries defined in SOAP headers that can be used to enforce policy-related decisions. You can choose from the following:

    • GenerateBearerToken specifies that a bearer token be generated.

    • AuthenticateRequester must be used with any service description that use SAML for message authentication.

    • EncryptResourceID specifies that the Discovery Service encrypt the resource ID.

    • AuthenticateSessionContext is specified when a Discovery Service provider includes a SAML assertion containing a SessionContextStatement in any future QueryResponse messages.

    • AuthorizeRequester is specified when a Discovery Service provider wants to include a SAML assertion containing a ResourceAccessStatement in any future QueryResponse messages.

    If you want to associate a directive with one or more service descriptions, select the check box for that Description ID. If no service descriptions are selected, the directive is applied to all description elements in the resource offering.

  24. Click OK.

  25. Logout from the console.

ProcedureTo Invoke the Custom Service

Web service clients can access the custom web service by discovering the web service's end point and using the required credentials. This information is stored by the Access Manager Discovery Service. There are two ways in which a client can authenticate to Access Manager in order to access the Discovery Service:

In the following procedure, we use the Liberty ID-WSF client API to invoke the web service.

Note –

The code in this procedure is used to demonstrate the usage of the Liberty ID-WSF client API. More information can be found in the Sun Java System Access Manager 7.1 Java API Reference.

  1. Write code to authenticate the WSC to the Authentication Web Service of Access Manager.

    The sample code below will allow access to the Discovery Service. It is a client-side program to be run inside the WSC application.

    public class StockClient {
        public SASLResponse authenticate(
            String userName,
            String password,
            String authurl) throws Exception {
            SASLRequest saslReq =
                            new SASLRequest(AuthnSvcConstants.MECHANISM_PLAIN);
            SASLResponse saslResp = AuthnSvcClient.sendRequest(saslReq, authurl);
            String statusCode = saslResp.getStatusCode();
            if (!statusCode.equals(SASLResponse.CONTINUE)) {
                    return null;
            String serverMechanism = saslResp.getServerMechanism();
            saslReq  = new SASLRequest(serverMechanism);
            String dataStr = userName + "\0" + userName + "\0" + password;
            saslResp = AuthnSvcClient.sendRequest(saslReq, authurl);
            statusCode = saslResp.getStatusCode();
            if (!statusCode.equals(SASLResponse.OK)) {
                return null;
            return saslResp;
  2. Add code that will extract the Discovery Service information from the Authentication Response.

    The following additional code would be added to what was developed in the previous step.

    ResourceOffering discoro = saslResp.getResourceOffering();
              List credentials = authnResponse.getCredentials();
  3. Add code to query the Discovery Service for the web service's resource offering by using the Discovery Service resource offering and the credentials that are required to access it.

    The following additional code would be added to what was previously developed.

    RequestedService rs = new RequestedService(null,
                  List rss = new ArrayList();
                 Query  discoQuery = new Query(discoro.getResourceID(), rss);
                 DiscoveryClient discoClient = null;
                 discoClient = new DiscoveryClient(secAssertion, serviceURL, null);
                 QueryResponse queryResponse = discoClient.getResourceOffering(discoQuery);
  4. The discovery response contains the service's resource offering and the credentials required to access the service.

    quotes contains the response body (the stock quote). You would use the Access Manager SOAP API to get the body elements.

     List offerings = discoResponse.getResourceOffering();
              ResourceOffering stockro = (ResourceOffering)offerings.get(0);
              List credentials = discoResponse.getCredentials();
              SecurityAssertion secAssertion = null;
              if(credentials != null && !credentials.isEmpty()) {
                 secAssertion = (SecurityAssertion)credentials.get(0);
              String serviceURL = ((Description)stockro.getServiceInstance().
              QuoteRequest req = new QuoteRequest(symbol,
              Element elem =  XMLUtils.toDOMDocument(
                  req.toString(), debug).getDocumentElement();
              List list = new ArrayList();
              Message msg = new Message(null, secAssertion);
              Message response = Client.sendRequest(msg, serviceURL, null, null);
              List quotes = response.getBodies();

Setting Up Liberty ID-WSF 1.1 Profiles

Access Manager automatically detects which version of the Liberty ID-WSF profiles is being used. If Access Manager is the web services provider (WSP), it detects the version from the incoming SOAP message. If Access Manager is the WSC, it uses the version the WSP has registered with the Discovery Service. If the WSP can not detect the version from the incoming SOAP message or the WSC can not communicate with the Discovery Service, the version defined in the com.sun.identity.liberty.wsf.version property in will be used. Following are the steps to configure Access Manager to use Liberty ID-WSF 1.1 profiles.

ProcedureTo Configure Access Manager to Use Liberty ID-WSF 1.1 Profiles

  1. Install Access Manager on two different machines.

    Test the installation by logging in to the console at http://server:port/amserver/UI/Login.

  2. Setup the two instances of Access Manager for communication using the Liberty ID-FF protocols.

    This entails setting up one instance as the service provider (SP) and the other as the identity provider (IDP). Instructions for doing this can be found in Entities and Authentication Domains or in the README file located in the /AccessManager-base/samples/liberty/sample1 directory.

    Note –

    This step also entails creating a keystore for each provider. Instructions for this procedure are located in /AccessManager-base/samples/saml/xmlsig/keytool.html or in Appendix B, Key Management in this guide. For testing purposes, you can copy the same keystore to each machine; if not, import the public keys from one machine to the other. Be sure to update the Key Alias attribute for each provider in and change the cookie name on one of the machines (in the same file) if both machines are in the same domain.

  3. Using the Access Manager console on the SP side, change the value of the Protocol Support Enumeration attribute to urn:liberty:iff:2003-08 in both provider configurations.

    The value of this attribute defines the supported release of the Liberty ID-FF; in this case, version 1.2.

  4. Setup the two instances of Access Manager for communication with the Liberty ID-WSF web services.

    This entails copying the files located in the /AccessManager-base/samples/phase2/wsc directory to your web container's doc root directory and making the changes specified in the sample README file. The relevant files and corresponding function are:

    • index.jsp: Retrieves boot strapping resource offering for Discovery Service.

    • discovery-modify.jsp: Adds resource offering for a user.

    • discovery-query.jsp: Sends query to Discovery Service for a resource offering.

    • id-sis-pp-modify.jsp: Sends Data Service Modify request to modify user attributes.

    • id-sis-pp-query.jsp: Sends Data Service Query request to retrieve user attributes.

  5. Copy the discovery-modify.jsp reproduced below into the web container's doc root directory.

    This JSP is configured to use the Liberty ID-WSF 1.1 Bearer token profile (<SecurityMechID>urn:liberty:security:2005-02:null:Bearer</SecurityMechID>) with appropriate directives and should replace the file already in the directory. You can modify this file to use other profiles if you know the defined URI of the particular Liberty ID-WSF 1.1 profile. (X509 or SAML token, for example.)

        Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved
        Use is subject to license terms.
    <%@page import="*,java.util.*,com.sun.identity.saml.common.*,*,*,*,,
    com.iplanet.sso.*,com.sun.liberty.LibertyManager" %>
    <html xmlns="">
    <head><title>Discovery Service Modification</title></head>
    <body bgcolor="white">
    <h1>Discovery Service Modification</h1>
        if (request.getMethod().equals("GET")) {
            String resourceOfferingFile =
            if (resourceOfferingFile == null) {
                resourceOfferingFile= "";
            String entryID =
            if (entryID == null) {
                entryID= "";
            // The following three values need to be changed to register a personal 
            // profile resource offering for a user.
            String ppProviderID = 
            String userDN = "uid=amAdmin,ou=People,dc=iplanet,dc=com";
            String ppEndPoint = 
            String providerID = request.getParameter("providerID");
            String ppResourceID = (new IDPPResourceIDMapper()).getResourceID(
                   ppProviderID, userDN);
            String newPPRO = 
                    "<ResourceOffering xmlns=\"urn:liberty:disco:2003-08\">" 
                    + "  <ResourceID>" + ppResourceID + "</ResourceID>\n"
                    + "  <ServiceInstance>\n"
                    + "    <ServiceType>urn:liberty:id-sis-pp:2003-08</ServiceType>\n"
                    + "    <ProviderID>" + ppProviderID + "</ProviderID>\n"
                    + "    <Description>"
                    + "      <SecurityMechID>urn:liberty:security:2005-02:null:Bearer"
                    + "</SecurityMechID>\n" 
                    + "      <Endpoint>" + ppEndPoint + "</Endpoint>\n"
                    + "    </Description>\n"
                    + "  </ServiceInstance>\n"
                    + "  <Abstract>This is xyz </Abstract>\n"
                    + "</ResourceOffering>";
    <form method="POST">
    <td>ResourceOffering (for discovery service itself)</td>
    <textarea rows="2" cols="30" name="discoResourceOffering">
    <%= resourceOfferingFile %>
    <td>PP ResourceOffering to add</td>
    <textarea rows="20" cols="60" name="insertStr"><%= newPPRO %></textarea>
    <td>AND/OR PP ResourceOffering to remove</td>
    <textarea rows="2" cols="30" name="entryID"></textarea>
    <input type="hidden" name="providerID" value="<%= providerID %>" />
    <input type="submit" value="Send Discovery Update Request" />
        } else {
            try {
                String resourceXMLFile = request.getParameter("discoResourceOffering");
          String resourceXML = null;
                try {
                     BufferedReader bir = new BufferedReader(
              new FileReader(resourceXMLFile));
                     StringBuffer buffer = new StringBuffer(2000);
                     int b1;
                     while (( ())!= -1) {
                     buffer.append((char) b1);
                     resourceXML = buffer.toString();
             } catch (Exception e) {
                	    %>Warning: cannot read disco resource offering.<%
                String insertString = request.getParameter("insertStr");
                String entryID = request.getParameter("entryID");
                String providerID = request.getParameter("providerID");
                if (resourceXML == null || resourceXML.equals("")) {
                    %>ERROR: resource offering missing<%
                } else {
                    ResourceOffering offering;
                try {
                     offering = new ResourceOffering(DiscoUtils.parseXML(
                        DiscoveryClient client = new DiscoveryClient(
                        Modify mod = new Modify();
                        if ((insertString != null) &&
         InsertEntry insert = new InsertEntry(
           new ResourceOffering(
    // Uncommnent the following when it's required.
                            List directives = new ArrayList();
                            Directive dir1 = new Directive(
    //                        Directive dir2 = new Directive(
    //                          Directive.AUTHORIZE_REQUESTER);
    //                        directives.add(dir2);
                            Directive dir3 = new Directive(
              List inserts = new ArrayList();
              if ((entryID != null) && !(entryID.equals(""))) {
                            RemoveEntry remove = new RemoveEntry(
                            List removes = new ArrayList();
                        if ((mod.getInsertEntry() == null) &&
                                    (mod.getRemoveEntry() == null))
                                %>ERROR: empty Modify<%
                        } else {
                                <h2>Formed Modify :</h2>
                                <pre><%= SAMLUtils.displayXML(mod.toString()) %></pre>
                                ModifyResponse resp2 = client.modify(mod);
                                <h2>Got result:</h2>
                                <pre><%= SAMLUtils.displayXML(resp2.toString()) %></pre>
                    } catch (Throwable t) {
                        StringWriter buf = new StringWriter();
                        t.printStackTrace(new PrintWriter(buf));
                            ERROR: caught exception:
                <p><a href="index.jsp">Return to index.jsp</a></p>
            } catch (Throwable e) {
                StringWriter buf = new StringWriter();
                e.printStackTrace(new PrintWriter(buf));
                    ERROR: oocaught exception:
  6. Modify the values of the following properties in on the IDP side to reflect the key alias. is located in /etc/opt/SUNWam/config. The following properties should be changed.




  7. Register the Liberty Personal Profile Service to the user defined by the userDN in discovery-modify.jsp.

    Under the default top-level realm on the instance of Access Manager acting as an IDP, go to Subjects and click User. Select the user and click Services. Click Add and register the Liberty Personal Profile Service.

    Note –

    In the discovery-modify.jsp reproduced above, the user is defined as the default administrator, amAdmin. See the line:

    String userDN = "uid=amAdmin,ou=People,dc=iplanet,dc=com";

  8. Restart both instances of Access Manager.

  9. Test that the Liberty ID-WSF 1.1 profiles are working by following the Run the Sample section of the README located in /AccessManager-base/samples/phase2/wsc.