, , ,

Как получить userName из WS-Security soap-заголовка, способ 2

вторник, 17 февраля 2009 г. Оставить комментарий

Я уже писал тут, как можно получить userName из soap-заголовка.
Теперь это можно сделать еще одним способом, зарегистрировав свой custom step в wsm.
Для этого в wsm идем по этой дорожке "Policy Management > Manage Policies > Steps", нажимаем "Add New Step" и указываем путь к конфигурационному xml-файлу своего custom step'а.

В файле указываем название шага, java-пакет, который реализует наш шаг, идентификатор, и одно свойство "Enabled" - разрешен или запрещен шаг.


<csw:StepTemplate
xmlns:csw="http://schemas.confluentsw.com/ws/2004/07/policy"
name="owsmcustomstep"
package="test_owsmcustomstep"
timestamp="Oct 15, 2007 05:00:00 PM"
version="1"
id="200902051">

<csw:Description>Custom step test</csw:Description>

<csw:Implementation>test_owsmcustomstep.CustomTestStep</csw:Implementation>

<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:PropertyDefinitions>
</csw:StepTemplate>

Ниже представлен класс, который реализует custom step.
Сначала получаем сообщение, возвращаем его в виде XML-документа. Находим имя пользователя и элемент, куда запишем это имя. После этого создаем новое сообщение на основе измененного XML-документа и возвращаем его.

package test_owsmcustomstep;

import com.cfluent.policysteps.sdk.AbstractStep;
import com.cfluent.policysteps.sdk.IMessageContext;
import com.cfluent.policysteps.sdk.IResult;
import com.cfluent.policysteps.sdk.Result;
import com.cfluent.policysteps.sdk.Fault;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import org.apache.axis.message.SOAPEnvelope;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class CustomTestStep extends AbstractStep {
private PrintWriter out = null;

public CustomTestStep() {
}

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

/**
* Used for cleaning up any resources created in the init() method
* It is called during server shutdown or when the policy is updated.
*/
public void destroy() {
out.close();
}

private void log(String str) {
try {
Date d = new Date();
DateFormat df = new SimpleDateFormat("HH:mm:ss yyyy/MM/dd");

out.println(df.format(d) + ":1158: " +str);
out.flush();
} catch (Exception ex) {
System.err.println("Exception encountered when writing to file");
ex.printStackTrace();
}
}

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

public IResult execute(IMessageContext messageContext) throws Fault {
log("CustomTestStep: Entering");

IResult resultStatus = new Result();
resultStatus.setStatus(IResult.FAILED);

try {
//Getting the SOAPMessage object from the context
SOAPMessage soapMessage = messageContext.getRequestMessage();
// loging request
logSOAPMessage(soapMessage);

SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = (SOAPEnvelope)soapPart.getEnvelope();

String namespaceURI_soap = "http://schemas.xmlsoap.org/soap/envelope/";
String namespaceURI_wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";

// get XML-Document
Document document = soapEnvelope.getAsDocument();
Element rootElement = document.getDocumentElement();
// element, where put username
Element elementInput = null;
String username = null;

// search username
if(rootElement != null) {
Element header = getToken(rootElement, "Header", namespaceURI_soap);
if(header != null) {
Element securityHeader = getToken(header, "Security", namespaceURI_wsse);
if(securityHeader != null) {
Element usernameTokenElement = getToken(securityHeader, "UsernameToken", namespaceURI_wsse);
if(usernameTokenElement != null) {
Element usernameElement = getToken(usernameTokenElement, "Username", namespaceURI_wsse);
if(usernameElement != null) {
username = usernameElement.getTextContent();
}
}
}
}
}

// search element
if(rootElement != null) {
String namespaceURI_ns1 = "http://xmlns.oracle.com/test_soap";
Element body = getToken(rootElement, "Body", namespaceURI_soap);
if(body != null) {
elementInput = getToken(body, "input", namespaceURI_ns1);
}
}

if (username != null && elementInput != null) {
elementInput.setTextContent(username);
}

//Convert the Document object to a String Object
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StringWriter strWriter = new StringWriter();
StreamResult streamResult = new StreamResult(strWriter);
transformer.transform(domSource, streamResult);
String xmlString = strWriter.toString();

//Convert this string object to a SOAPMessage object
MessageFactory messageFactory = MessageFactory.newInstance();
MimeHeaders mimeheaders = new MimeHeaders();
mimeheaders.addHeader("Content-Type", "text/xml");

// IMPORTANT : The following is very important especially if your
// SOAP message would contain UTF-8 data like European characters etc.
ByteArrayInputStream soapByteArrayInputStream = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
SOAPMessage newSoapMessage = messageFactory.createMessage(mimeheaders, soapByteArrayInputStream);

//Set the SOAP Request back into the context
messageContext.setRequestMessage(newSoapMessage);

// logging new request
logSOAPMessage(messageContext.getRequestMessage());
log("CustomTestStep: Exiting");
resultStatus.setStatus(IResult.SUCCEEDED);

} catch (Exception ex) {
String errMsg = ex.getMessage();
log("CustomTestStep: Error:" + errMsg);
generateFault(errMsg);
}

return resultStatus;
}

private Element getToken(Element parentElement, String tokenName, String tokenNameSpaceURI)
{
Element token = null;
NodeList nodeList = parentElement.getElementsByTagNameNS(tokenNameSpaceURI, tokenName);
if (nodeList != null) {
token = (Element)nodeList.item(0);
}
return token;
}

}

Примеры для создания custom step в WSM можно найти на metalink:How To read a SOAP Message into an XML Document & back into a SOAP Message?

0 коммент. »

Оставьте Ваш комментарий