Sun Java System Access Manager 7.1 Federation and SAML Administration Guide

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 com.sun.identity.liberty.ws.soapbinding.RequestHandler 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 QuoteRequest.java and QuoteResponse.java to parse and process the XML messages.

    <?xml version="1.0" encoding="UTF-8" ?> 
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns="urn:com:sun:liberty:sample:stockticker"
      targetNamespace="urn:com:sun:liberty:sample:stockticker">
      <xs:annotation>
          <xs:documentation>
             This is a sample stock ticker web service protocol
          </xs:documentation>
      </xs:annotation>
    
      <xs:element name="QuoteRequest" type="QuoteRequestType"/>
      <xs:complexType name="QuoteRequestType">
        <xs:sequence>
            <xs:element name = "ResourceID" type="xs:string" minOccurs="0"/>
            <xs:element name = "Symbol" type="xs:string" minOccours="1"/>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="PriceType">
          <xs:sequence>
              <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:sequence>
      </xs:complexType>
    
      <xs:element name="QuoteResponse" type="QuoteResponseType"/>
      <xs:complexType name="QuoteResponseType">
        <xs:sequence>
            <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"/>
        </xs:sequence>
      </xs:complexType>
    
    </xs:schema>
  2. Provide an implementation for one of the following interfaces based on the type of web service being developed:

    • com.sun.identity.liberty.ws.soapbinding.RequestHandler for developing and deploying a general web service.

      See SOAP Binding Service Package.

    • com.sun.identity.liberty.ws.dst.service.DSTRequestHandler 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 com.sun.identity.liberty.ws.dst.service 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 com.sun.identity.liberty.ws.soapbinding.RequestHandler interface for the stock quote web service. com.sun.identity.liberty.ws.soapbinding.Message 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();
                    response.setBodies(responseBody);
     
                    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:


    http://SERVER_HOST:SERVER_PORT/SERVER_DEPLOY_URI/Liberty/stock
  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:


      http://SERVER_HOST:SERVER_PORT/SERVER_DEPLOY_URI/Liberty/stock
    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);
            saslReq.setAuthzID(userName);
    
            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;
            saslReq.setData(dataStr.getBytes("UTF-8"));
            saslReq.setRefToMessageID(saslResp.getMessageID());
            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,
                       "urn:com:sun:liberty:sample:stockticker");
                  List rss = new ArrayList();
                  rss.add(rs);
    
                 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().
                       getDescription().get(0)).getEndpoint();
    
              QuoteRequest req = new QuoteRequest(symbol,
                   stockro.getResourceID().getResourceID());
              Element elem =  XMLUtils.toDOMDocument(
                  req.toString(), debug).getDocumentElement();
    
              List list = new ArrayList();
              list.add(elem);
    
              Message msg = new Message(null, secAssertion);
              msg.setSOAPBodies(list);
    
              Message response = Client.sendRequest(msg, serviceURL, null, null);
              List quotes = response.getBodies();