1

SOAP WS があり、WS-Security ユーザー名トークンを追加する必要があります。サービスへのアクセスを許可または拒否するためにユーザー名と pwd を探して soapHeader を解析するサーバー側の SoapHandler (実装クラスに @HandlerChain(file="handler-chain.xml") に注釈を付ける) を実装しました。これは usernametoken セキュリティを処理する正しい方法ですか、それともより良い方法がありますか? 私のハンドラーは次のとおりです。

public class 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のインスタンスではないため、ユーザー名とpwdを解析しません。どうすればこれを解決できますか? 前もって感謝します。

4

0 に答える 0