Skip Headers
Oracle® Web Services Manager Extensibility Guide
10g (10.1.3.3.0)

Part Number E10300-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

A Custom Step Source Code and Step Template

This appendix lists the source code (Example A-1) and step template (Example A-2) for the custom authentication step sample described in Chapter 2, "Understanding the Sample Custom Step".

Custom Step Source Code

Example A-1 is the source code for the custom authentication step sample. The file containing this code, CustomAuthenticationStep.java, can be found in the ORACLE_HOME\owsm\samples\customsteps\customAuthenticationStep directory.

Example A-1 Custom Authentication Step Source Code

package customsteps;

import com.cfluent.policysteps.sdk.*;
import javax.servlet.http.HttpServletRequest;
import javax.xml.soap.*;
import java.io.*;
import java.util.Locale;
import java.util.Iterator;

public class CustomAuthenticationStep extends AbstractStep {
  private String expectedUsername = null;
  private String expectedUserPassword = null;
  private PrintWriter out = null;
  public CustomAuthenticationStep() {
  }

  public void init() throws IllegalStateException {
    try {
      out = new PrintWriter(new BufferedWriter(new FileWriter("log/CustomAuthenticationStep.log", true)));
    } catch (Exception e) {
      String errMsg = "Error in creating log file for custom authentication step:" + e.getMessage();
      System.err.println(errMsg);
      e.printStackTrace();
    throw new IllegalStateException(errMsg);
    }
  }

  public void destroy() {
    out.close();
  }

  public IResult execute (IMessageContext messageContext) throws Fault {
    log("********** Entering Custom Authentication execute method **********");
    Result result = new Result();
    result.setStatus(IResult.FAILED);//initialize result

    String processingStage = messageContext.getProcessingStage();
    log("Processing stage is " + processingStage);
    boolean isRequest = 
      (IMessageContext.STAGE_REQUEST.equals(messageContext.getProcessingStage()) || IMessageContext.STAGE_PREREQUEST.equals(messageContext.getProcessingStage()));
    
    if(!isRequest) {
      // This step is applicable only for request pipelines
      result.setStatus(IResult.SUCCEEDED);
      return result;
    }

    // get SOAP message to access various parts of it
    javax.xml.soap.SOAPMessage soapMessage = messageContext.getRequestMessage();
    // Log the request SOAP message
    logSOAPMessage(soapMessage);

    //get user locale
    Locale userLocale = messageContext.getUserLocale();
    log("User locale is " +userLocale.getDisplayName());

    // get HTTP Header containing client IP address
    HttpServletRequest httpServletRequest = (HttpServletRequest)messageContext.getProperty("javax.servlet.request");
    String remoteAddr = httpServletRequest.getHeader("Host");
    log("Client ip address is " + remoteAddr);

    String verifiedUser = null;
    try {
      verifiedUser = authenticate(soapMessage);
      // set result status
      result.setStatus(IResult.SUCCEEDED);
    } catch (Exception ex) {
      String errMsg = ex.getMessage();
      log(errMsg);
      // set monitoring data for failed authentication
      messageContext.getInvocationStatus();setAuthenticationStatus (InvocationStatus.FAILED);
      messageContext.getInvocationStatus().setErrorMessage(errMsg);
      // if you use this method, the Fault will be populated with appropriate fault code
      // (AuthenticateFault for this custom step)
      generateFault(errMsg);
    }

    log("Verified user is " + verifiedUser);

    // set monitoring data for successful authentication
    messageContext.getInvocationStatus().setAuthenticationStatus (InvocationStatus.SUCCEEDED);

    return result;
  }

  private String authenticate(SOAPMessage soapMessage) throws Exception {
    // Get username and password from Security header
    String username = null;
    String password = null;
    String namespaceURI ="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-wssecurity-secext-1.0.xsd";

    SOAPHeader soapHeader = soapMessage.getSOAPPart().getEnvelope().getHeader();
    if(soapHeader != null) {
      SOAPElement securityHeader = getToken(soapHeader, "Security", namespaceURI);
      if(securityHeader != null) {
        SOAPElement username TokenElement = getToken(securityHeader, "UsernameToken", namespaceURI);
        if(usernameTokenElement != null) {
          SOAPElement usernameElement = getToken(username TokenElement, "Username", namespaceURI);
          SOAPElement passwordElement = getToken(username TokenElement, "Password", namespaceURI);
          if(usernameElement != null) username = usernameElement.getValue();
          if(usernameElement != null) password = passwordElement.getValue();
        }
      }
    }

    if(username == null) {
      String msg = "Authentication failed: Username not supplied";
      throw new Exception (msg);
    }

    // authenticate against the configured userid and password.
    // This can be against any custom datastore as well.
    if(!expectedUsername.equals(username) || !expectedUserPassword.equals(password)) {
      String msg = "Authentication failed for user " + username;
      throw new Exception(msg);
    }

    return username;
  }

  private SOAPElement getToken(SOAPElement element, String tokenName, String nameSpaceURI)
  throws Exception
  {
      SOAPElement token = null;
      SOAPFactory factory = SOAPFactory.newInstance();
    Name localName = factory.createName(tokenName, "", nameSpaceURI);
    Iterator iter = element.getChildElements(localName);

    if(iter.hasNext()) token = (SOAPElement) iter.next();
    return token;
  }

  private void logSOAPMessage(javax.xml.soap.SOAPMessage soapMsg) {
    String msg = null;
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      soapMsg.writeTo(baos);
      msg = baos.toString();
      log("Request SOAP message is " + msg);
    } catch (Exception ex) {
      System.err.println("Exception encountered while converting SOAP message to a String");
      ex.printStackTrace();
    }
  }

  private void log(String str) {
    try {
      out.println(str);
      out.flush();
    } catch (Exception ex) {
      System.err.println("Exception encountered while writing to file");
      ex.printStackTrace();
    }
  }

  public String getUsername() {
    return expectedUsername;
  }

  public void setUsername(String username) {
    this.expectedUsername = username;
  }

  public String getPassword() {
    return expected UserPassword;
  }

  public void setPassword(String password) {
    this.expectedUserPassword = password;
  }
}

Custom Step Template

Example A-2 lists the custom step template for the custom authentication step sample:

Example A-2 Step Template (CustomAuthenticationStep.xml)

<csw:StepTemplate xmlns:csw="http://schemas.confluentsw.com/ws/2004/07/policy" name="Custom Authenticate step" package="customsteps" timestamp="Oct 31, 2005 05:00:00 PM" version="1" id="118970829">
  <csw:Description>Custom step that authenticates the user against the credentials entered here.</csw:Description>
  <csw:Implementation>customsteps.CustomAuthenticationStep</csw:Implementation>
  <csw:Faults>
    <csw:Fault xmlns:fns="http://schemas.oblix.com/ws/2003/08/Faults">fns:AuthenticationFault</csw:Fault>
</csw:Faults>
  <csw:PropertyDefinitions>
    <csw:PropertyDefinitionSet name="Basic Properties">
      <csw:PropertyDefinition name="Enabled" type="boolean">
        <csw:Description>If set to true, this step is enabled</csw:Description>
        <csw:DefaultValue>
          <csw:Absolute>true</csw:Absolute>
        </csw:DefaultValue>
      </csw:PropertyDefinition>
    </csw:PropertyDefinitionSet>
    <csw:PropertyDefinitionSet name="User Credentials">
      <csw:PropertyDefinition name="Username" type="string" isRequired="true">
        <csw:DisplayName>Username</csw:DisplayName>
        <csw:Description>Username used for authentication</csw:Description>
        <csw:DefaultValue>
          <csw:Absolute>test</csw:Absolute>
        </csw:DefaultValue>
      </csw:PropertyDefinition>
      <csw:PropertyDefinition name="Password" type="string" isRequired="true" displayType="password">
        <csw:DisplayName>Password</csw:DisplayName>
        <csw:Description>Password used for authentication</csw:Description>
        <csw:DefaultValue>
          <csw:Absolute>test</csw:Absolute>
        </csw:DefaultValue>
      </csw:PropertyDefinition>
    </csw:PropertyDefinitionSet>
  </csw:PropertyDefinitions>
</csw:StepTemplate>