Package web.header

Source Code of web.header.SignHandler

package web.header;
/*
* Copyright 2004, 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$Factory
*/

/* 
* Note:  This sample was developed based on the example in the article:
* http://www-128.ibm.com/developerworks/webservices/library/ws-tip-extend/
*/
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.rpc.handler.Handler;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;


/**
* Provides common behavior for client & service handlers,
* generalized as outgoing and incoming message processing.
*/
abstract class SignHandler implements Handler
{
    /**
     * Header element namespace
     */
    private static final String SIGN_NS_URI
        = "uri://org.example.webservices.signature.Sign";

    /**
     * Header element namespace prefix
     */
    private static final String SIGN_PREFIX
        = "sign";

    /**
     * Header element
     */
    private static final String SIGN_ELEMENT
        = "sign";

    /**
     * Header element qualifed name
     */
    private static final QName SIGN_HEADER
        = new QName(SIGN_NS_URI, SIGN_ELEMENT);


    private SignatureTool signatureTool
        = new SignatureToolImpl();

    private HandlerInfo info;


    /**
     * Name of required property, in HandlerInfo handler configuration,
     * that specifies who signs outgoing messages.
     */
    public  static final String SIGNERS_NAME_PROPERTY
        = "org.example.webservices.signature.SignersName";
   
    /**
     * Set of SOAP headers that this handler knows how to process.
     * It is expected that this is set on the HandlerInfo for
     * instances of this handler's subclasses.
     */
    public  static final QName[] HEADERS
        = new QName[] { SIGN_HEADER };


    public void init(HandlerInfo config) {
        info = config;
    }

    public void destroy() {}

    public QName[] getHeaders() { return info.getHeaders(); }


    /**
     * Obtain signers name from handler configuration (HandlerInfo),
     * and sign message.
     * @throws SignException if SIGNERS_NAME_PROPERTY is not available
     *                       in the handler config.
     */
    public void signOutgoing(SOAPMessageContext mc) throws SignException {
        /**
         * SIGNERS_NAME_PROPERTY is required to be on the configuration.
         */
        Map config = info.getHandlerConfig();
        if (config == null) {
            throw new SignException("Signers Name not provided");
        }

        Object nameObj = config.get(SIGNERS_NAME_PROPERTY);
        if (!(nameObj instanceof String)) {
            throw new SignException("Signers Name not provided");
        }
       
        String name = (String)nameObj;
       

        try {
            /**
             * Dig down into message, locate or create header block.
             */
            SOAPMessage msg = mc.getMessage();
            SOAPPart part = msg.getSOAPPart();
            SOAPEnvelope envelope = part.getEnvelope();
       
            SOAPHeader header = envelope.getHeader();
            if (header == null) {
                header = envelope.addHeader();
            }
           
            /**
             * Create new header element.
             * Use simple-security as role
             */
            SOAPHeaderElement headerElement
                = (SOAPHeaderElement)header.addChildElement(SIGN_ELEMENT,
                                                            SIGN_PREFIX,
                                                            SIGN_NS_URI);
            headerElement.setActor("simple-security");
//  Just sign with name in the header, leave the content alone
//            /**
//             * Locate portion of message content that is to be signed.
//             */
//            SOAPElement content = getContent(part);

            /**
             * Create new element representing signature,
             * and add as child to new header element.
             */
            SOAPElement element = signatureTool.getSignature(name);   //, content);
            headerElement.addChildElement(element);
        } catch (SOAPException e) {
            e.printStackTrace();
            throw new SignException("Unable to sign message", e);
        }
    }


    /**
     * Look for signature on incoming message.
     * If signature not found, then continue message processing.
     * If signature is found, then verify that it is "correct".
     * If correct, then continue message processing.
     * If not correct, then throw SignException.
     */
    public void checkIncoming(SOAPMessageContext mc) throws SignException {
        int     validSignatures = 0;
        boolean expectedSignature = false;

        try {
            SOAPMessage msg = mc.getMessage();
            SOAPPart part = msg.getSOAPPart();
            SOAPEnvelope envelope = part.getEnvelope();

           
//            /**
//             * Locate portion of message content that is to be signed.
//             */
//            SOAPElement content = getContent(part);


            /**
             * Dig down through SOAP headers looking for matches to
             * SIGN_HEADER, that are also targeted for this SOAP Node.
             */
            SOAPHeader header = envelope.getHeader();
            if (header != null) {
                /**
                 * The roles the node acts in are specified by the
                 * MessageContext.getRoles() method.  This code
                 * examines each role independently.
                 */
                String[] roles = mc.getRoles();

                /**
                 * If no roles are found, then default to
                 * "ultimate destination".
                 */
                if (roles == null  ||  roles.length == 0) {
                    System.out.println("checkIncoming: no roles, " +
                                       "default to ultimate destination");
                    roles = new String[] { "" };
                }

                /**
                 * Examine headers bound to each role this node acts in.
                 */
                for (int ridx = 0; ridx < roles.length; ridx++) {
                    String role = roles[ridx];

                    System.out.println("checkIncoming: role == \"" +
                                       role + "\"");
                   
                    /**
                     * Headers are determined to be targeted for a SOAP Node by
                     * matching the node's roles with the header's actor role.
                     *
                     * So now go through list of headers associated with
                     * the role we are currently working on.
                     */
                    Iterator headerElementIter
                        = header.examineHeaderElements(role);
   
                    while (headerElementIter.hasNext()) {
                        SOAPHeaderElement headerElement
                            = (SOAPHeaderElement)headerElementIter.next();
   
                        /**
                         * Is header recognized by this handler?
                         */
                        Name headerElementName
                            = headerElement.getElementName();

                        if (equals(headerElementName, SIGN_HEADER)) {
                            System.out.println("checkIncoming: header match" +
                                               ": \"" +
                                               elementName(headerElementName) +
                                               "\"");

                            /**
                             * We got this far, we expect a signature now.
                             */
                            expectedSignature = true;

                            /**
                             * Look for SOAPElement(s) in header,
                             * ignoring mixed content.
                             */
                            Iterator headerIter
                                = headerElement.getChildElements();
   
                            while (headerIter.hasNext()) {
                                Object elementObj = headerIter.next();
   
                                if (elementObj instanceof SOAPElement) {
                                    SOAPElement element
                                        = (SOAPElement)elementObj;

                                    signatureTool.isSignatureValid(element); //,content);
                                    validSignatures++;
                                }
                            }
                        }
                    }
                }
            } else {
                System.out.println("Header not found!");
            }
        } catch (SOAPException e) {
            e.printStackTrace();
            throw new SignException("Unable to verify signature", e);
        }
       
        /**
         * Throw an exception if we ever got to a point where we
         * expected a signature, but then we never found one
         * [this logic is weak, but sufficient].
         */
        if (expectedSignature && validSignatures < 1) {
            throw new SignException("Expected signature(s) not found");
        }
    }
   
    /**
     * Compare two qnames
     */
    private boolean equals(Name name, QName qname) {
        return (name == null  &&  qname == null) ||
               (name.getURI().equals(qname.getNamespaceURI()) &&
                name.getLocalName().equals(qname.getLocalPart()));
    }
   
//    /**
//     * Helper method, return content of SOAPPart that we want to sign.
//     */
//    private SOAPElement getContent(SOAPPart part) throws SOAPException {
//        SOAPEnvelope envelope = part.getEnvelope();
//        return envelope.getBody();
//    }

    /**
     * Return name of SOAPElement as a String.
     */
    private String elementName(SOAPElement e) {
        return elementName(e.getElementName());
    }
   
    /**
     * Return name of SOAPElement as a String.
     */
    private String elementName(Name name) {
        return "{" + name.getURI() + "}" + name.getLocalName();
    }
}
TOP

Related Classes of web.header.SignHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.