使用usernametoken的WS-Security

时间:2016-11-29 17:38:14

标签: java soap ws-security usernametoken soaphandler

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

公共类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的实例,因此它不会解析我的用户名和密码。我怎么能解决这个问题?提前谢谢。

0 个答案:

没有答案