DarkAngeL
DarkAngeL

Reputation: 439

WS-Security with usernametoken

I have a soap WS and need to add the WS-Security usernametoken. I have implemented server side a SoapHandler (annotating @HandlerChain(file="handler-chain.xml") the implementation class) that should parse the soapHeader looking for the username and pwd to allow or deny the access to the service. Is this a correct way to handle usernametoken security or there is a better one? my handler is:

public class SecurityValidatorHandler implements SOAPHandler{

private static final String WSSE_NS_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final QName QNAME_WSSE_USERNAMETOKEN = new QName(WSSE_NS_URI, "UsernameToken");
private static final QName QNAME_WSSE_USERNAME = new QName(WSSE_NS_URI, "Username");
private static final QName QNAME_WSSE_PASSWORD = new QName(WSSE_NS_URI, "Password");


@Override
public boolean handleMessage(SOAPMessageContext context) {

    Boolean outbound = (Boolean) context
            .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    if ((outbound != null) && (!outbound.booleanValue())) {
        handleInboundMessage(context);
    }
    return true;
}


@Override
public boolean handleFault(SOAPMessageContext context) {

    System.out.println("Server : handleFault()......");

    return true;
}

@Override
public void close(MessageContext context) {
    System.out.println("Server : close()......");
}

@Override
public Set<QName> getHeaders() {
    System.out.println("Server : getHeaders()......");
    return null;
}

private void generateSOAPErrMessage(SOAPMessage msg, String reason) {
    try {
        System.out.println("Generating exception");
        SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
        SOAPFault soapFault = soapBody.addFault();
        soapFault.setFaultString(reason);
        throw new SOAPFaultException(soapFault);
    }
    catch(SOAPException e) { }
}

private void handleInboundMessage(SOAPMessageContext context) {
    String wsseUsername = null;
    String wssePassword = null;
    try {
        SOAPHeader header = context.getMessage().getSOAPHeader();
        Iterator<?> headerElements = header.examineAllHeaderElements();

        while (headerElements.hasNext()) {
            SOAPHeaderElement headerElement = (SOAPHeaderElement) headerElements
                    .next();
            //System.out.println(headerElement.getActor() + " " + headerElement.getRole() + " " + headerElement.getValue());

            if (headerElement.getElementName().getLocalName()
                    .equals("Security")) {
                SOAPHeaderElement securityElement = headerElement;
                Iterator<?> it2 = securityElement.getChildElements();

                while (it2.hasNext()) {

                    Node soapNode = (Node) it2.next();
                    if (soapNode instanceof SOAPElement) {
                        SOAPElement element = (SOAPElement) soapNode;
                        QName elementQname = element.getElementQName();
                        if (QNAME_WSSE_USERNAMETOKEN.equals(elementQname)) {
                            SOAPElement usernameTokenElement = element;
                            wsseUsername = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_USERNAME);
                            wssePassword = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_PASSWORD);

                            System.out.println(wsseUsername);
                            System.out.println(wssePassword);
                            break;
                        }
                    }

                    if (wsseUsername != null) {
                        break;
                    }
                    if(!"mypwd".equalsIgnoreCase(wssePassword)){
                        generateSOAPErrMessage(context.getMessage(), "access denied");
                    }
                }
            }
            context.put("USERNAME", wsseUsername);
            context.setScope("USERNAME", Scope.APPLICATION);

            context.put("PASSWORD", wssePassword);
            context.setScope("PASSWORD", Scope.APPLICATION);
        }
    } catch (SOAPException e) {
        System.out.println("Error reading SOAP message context: " + e);
        e.printStackTrace();
    }

}

private String getFirstChildElementValue(SOAPElement soapElement, QName qNameToFind) {
    String value = null;
    Iterator<?> it = soapElement.getChildElements(qNameToFind);
    while (it.hasNext()) {
        SOAPElement element = (SOAPElement) it.next(); //use first
        value = element.getValue();
    }
    return value;
}

}

But this way its not working since when trying to check

if (soapNode instanceof SOAPElement) 

for casting the element its not an instance of SOAPElement so its not parsing my username and pwd. How could i solve this? Thanks in advance.

Upvotes: 1

Views: 1140

Answers (0)

Related Questions