| Oracle® Web Services Manager Extensibility Guide 10g (10.1.3.3.0) Part Number E10300-01 |
|
|
View PDF |
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".
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;
}
}
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>