public XMLSecEvent processEvent()

in ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/SecurityHeaderInputProcessor.java [72:180]


    public XMLSecEvent processEvent(InputProcessorChain inputProcessorChain)
            throws XMLStreamException, XMLSecurityException {

        //buffer all events until the end of the security header
        final InputProcessorChain subInputProcessorChain = inputProcessorChain.createSubChain(this);
        final InternalSecurityHeaderBufferProcessor internalSecurityHeaderBufferProcessor
                = new InternalSecurityHeaderBufferProcessor(getSecurityProperties());
        subInputProcessorChain.addProcessor(internalSecurityHeaderBufferProcessor);

        boolean responsibleSecurityHeaderFound = false;
        boolean timestampFound = false;

        XMLSecEvent xmlSecEvent;
        do {
            subInputProcessorChain.reset();
            xmlSecEvent = subInputProcessorChain.processHeaderEvent();

            switch (xmlSecEvent.getEventType()) {   //NOPMD
                case XMLStreamConstants.START_ELEMENT:
                    XMLSecStartElement xmlSecStartElement = xmlSecEvent.asStartElement();
                    int documentLevel = xmlSecStartElement.getDocumentLevel();

                    if (documentLevel == 1) {
                        if (WSSUtils.getSOAPMessageVersionNamespace(xmlSecStartElement) == null) {
                            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, "notASOAPMessage");
                        }
                    } else if (documentLevel == 3
                            && xmlSecStartElement.getName().equals(WSSConstants.TAG_WSSE_SECURITY)
                            && WSSUtils.isInSOAPHeader(xmlSecStartElement)) {

                        if (!WSSUtils.isResponsibleActorOrRole(xmlSecStartElement,
                                ((WSSSecurityProperties) getSecurityProperties()).getActor())) {
                            continue;
                        }
                        responsibleSecurityHeaderFound = true;

                    } else if (documentLevel == 4 && responsibleSecurityHeaderFound
                            && WSSUtils.isInSecurityHeader(xmlSecStartElement,
                            ((WSSSecurityProperties) getSecurityProperties()).getActor())) {
                        startIndexForProcessor = xmlSecEventList.size() - 1;

                        //special handling for EncryptedData in the SecurityHeader. This way, if for example
                        // a token was encrypted we have the possibility to decrypt it before so that we
                        // are able to engage the appropriate processor for the token.
                        if (WSSConstants.TAG_xenc_EncryptedData.equals(xmlSecStartElement.getName())) {
                            engageSecurityHeaderHandler(subInputProcessorChain, getSecurityProperties(),
                                    xmlSecEventList, startIndexForProcessor, xmlSecStartElement.getName());
                        }
                    } else if (documentLevel == 5 && responsibleSecurityHeaderFound
                            && WSSUtils.isInSecurityHeader(xmlSecStartElement,
                            ((WSSSecurityProperties) getSecurityProperties()).getActor())
                            && WSSConstants.TAG_xenc_EncryptedData.equals(xmlSecStartElement.getName())) {
                        startIndexForProcessor = xmlSecEventList.size() - 1;

                        // Same goes as per EncryptedData above. This is when a child of a security header
                        // element is encrypted (e.g. EncryptedAssertion)
                        engageSecurityHeaderHandler(subInputProcessorChain, getSecurityProperties(),
                                xmlSecEventList, startIndexForProcessor, xmlSecStartElement.getName());
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    XMLSecEndElement xmlSecEndElement = xmlSecEvent.asEndElement();
                    documentLevel = xmlSecEndElement.getDocumentLevel();
                    if (documentLevel == 3 && responsibleSecurityHeaderFound
                            && xmlSecEndElement.getName().equals(WSSConstants.TAG_WSSE_SECURITY)) {

                        return finalizeHeaderProcessing(
                                inputProcessorChain, subInputProcessorChain,
                                internalSecurityHeaderBufferProcessor, xmlSecEventList);

                    } else if (documentLevel == 4 && responsibleSecurityHeaderFound
                            && WSSUtils.isInSecurityHeader(xmlSecEndElement,
                            ((WSSSecurityProperties) getSecurityProperties()).getActor())) {
                        //we are in the security header and the depth is +1, so every child
                        //element should have a responsible handler with the exception of an EncryptedData SecurityHeader
                        //which is already handled in the above StartElement Logic (@see comment above).
                        if (!WSSConstants.TAG_xenc_EncryptedData.equals(xmlSecEndElement.getName())) {
                            engageSecurityHeaderHandler(subInputProcessorChain, getSecurityProperties(),
                                    xmlSecEventList, startIndexForProcessor, xmlSecEndElement.getName());
                        }

                        // Check for multiple timestamps
                        if (xmlSecEndElement.getName().equals(WSSConstants.TAG_WSU_TIMESTAMP)) {
                            if (timestampFound) {
                                WSInboundSecurityContext context =
                                    (WSInboundSecurityContext)subInputProcessorChain.getSecurityContext();
                                context.handleBSPRule(BSPRule.R3227);
                            }
                            timestampFound = true;
                        }
                    }
                    break;
            }

        } while (!(xmlSecEvent.getEventType() == XMLStreamConstants.START_ELEMENT
                && xmlSecEvent.asStartElement().getName().getLocalPart().equals(WSSConstants.TAG_SOAP_BODY_LN)
                && xmlSecEvent.asStartElement().getName().getNamespaceURI().equals(
                WSSUtils.getSOAPMessageVersionNamespace(xmlSecEvent.asStartElement()))
        ));
        //if we reach this state we didn't find a security header
        //issue a security event to notify about this fact:
        NoSecuritySecurityEvent noSecuritySecurityEvent = new NoSecuritySecurityEvent();
        noSecuritySecurityEvent.setCorrelationID(IDGenerator.generateID(null));
        inputProcessorChain.getSecurityContext().registerSecurityEvent(noSecuritySecurityEvent);

        return finalizeHeaderProcessing(
                inputProcessorChain, subInputProcessorChain,
                internalSecurityHeaderBufferProcessor, xmlSecEventList);
    }