1

我有一个肥皂 WS,需要添加 WS-Security usernametoken。我已经在服务器端实现了一个 SoapHandler(注释 @HandlerChain(file="handler-chain.xml") 实现类),它应该解析soapHeader 以查找用户名和密码以允许或拒绝对服务的访问。这是处理用户名令牌安全性的正确方法还是有更好的方法?我的处理程序是:

公共类 SecurityValidatorHandler 实现 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;
}

}

但是这种方式在尝试检查时不起作用

if (soapNode instanceof SOAPElement) 

用于转换元素,它不是 SOAPElement 的实例,因此它不解析我的用户名和密码。我怎么能解决这个问题?提前致谢。

4

0 回答 0