blob: 2faad4365f2849d1724a6cc3236202d43b787679 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.wss4j.dom.processor;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import javax.xml.namespace.QName;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.util.XMLUtils;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.WSDataRef;
import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.RequestData;
/**
* This will process incoming <code>saml2:EncryptedAssertion</code> elements.
*/
public class EncryptedAssertionProcessor implements Processor {
private static final org.slf4j.Logger LOG =
org.slf4j.LoggerFactory.getLogger(EncryptedAssertionProcessor.class);
public List<WSSecurityEngineResult> handleToken(
Element elem,
RequestData request
) throws WSSecurityException {
LOG.debug("Found EncryptedAssertion element");
Element encryptedDataElement =
XMLUtils.getDirectChildElement(elem, WSConstants.ENC_DATA_LN, WSConstants.ENC_NS);
if (encryptedDataElement == null) {
// Maybe it has already been decrypted...
return Collections.emptyList();
}
List<WSSecurityEngineResult> completeResults = new LinkedList<>();
// Check all EncryptedKey elements
for (Node currentChild = elem.getFirstChild();
currentChild != null;
currentChild = currentChild.getNextSibling()
) {
if (Node.ELEMENT_NODE == currentChild.getNodeType()
&& "EncryptedKey".equals(currentChild.getLocalName())
&& WSConstants.ENC_NS.equals(currentChild.getNamespaceURI())) {
QName el =
new QName(((Element)currentChild).getNamespaceURI(),
((Element)currentChild).getLocalName());
Processor proc = request.getWssConfig().getProcessor(el);
if (proc != null) {
completeResults.addAll(proc.handleToken((Element)currentChild, request));
}
}
}
// If we have processed EncryptedKey elements, then the Assertion is already decrypted
// at this point. Process it accordingly.
if (!completeResults.isEmpty()) {
for (WSSecurityEngineResult r : completeResults) {
@SuppressWarnings("unchecked")
List<WSDataRef> dataRefs =
(List<WSDataRef>)r.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
if (dataRefs != null) {
for (WSDataRef dataRef : dataRefs) {
if (WSConstants.SAML_TOKEN.equals(dataRef.getName())
|| WSConstants.SAML2_TOKEN.equals(dataRef.getName())) {
// Get hold of the plain text element
Element decryptedElem = dataRef.getProtectedElement();
QName el = new QName(decryptedElem.getNamespaceURI(), decryptedElem.getLocalName());
Processor proc = request.getWssConfig().getProcessor(el);
if (proc != null) {
LOG.debug("Processing decrypted element with: {}", proc.getClass().getName());
List<WSSecurityEngineResult> results = proc.handleToken(decryptedElem, request);
completeResults.addAll(0, results);
return completeResults;
}
}
}
}
}
}
// Otherwise decrypt the element ourselves
// Type must be "Element" if specified
String typeStr = encryptedDataElement.getAttributeNS(null, "Type");
if (typeStr != null && !(WSConstants.ENC_NS + "Element").equals(typeStr)) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.INVALID_SECURITY, "badElement",
new Object[] {"Element", typeStr}
);
}
// Now hand it off to another processor (EncryptedDataProcessor)
QName el =
new QName(encryptedDataElement.getNamespaceURI(), encryptedDataElement.getLocalName());
Processor proc = request.getWssConfig().getProcessor(el);
if (proc != null) {
LOG.debug("Processing decrypted element with: {}", proc.getClass().getName());
return proc.handleToken(encryptedDataElement, request);
}
return Collections.emptyList();
}
}