in ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/SAMLTokenInputHandler.java [103:227]
public void handle(final InputProcessorChain inputProcessorChain, final XMLSecurityProperties securityProperties,
Deque<XMLSecEvent> eventQueue, Integer index) throws XMLSecurityException {
final Document samlTokenDocument = (Document) parseStructure(eventQueue, index, securityProperties);
final WSSSecurityProperties wssSecurityProperties = (WSSSecurityProperties) securityProperties;
final WSInboundSecurityContext wsInboundSecurityContext = (WSInboundSecurityContext) inputProcessorChain.getSecurityContext();
final Element samlElement = samlTokenDocument.getDocumentElement();
final SamlAssertionWrapper samlAssertionWrapper = new SamlAssertionWrapper(samlElement);
SamlTokenValidator samlTokenValidator =
wssSecurityProperties.getValidator(new QName(samlElement.getNamespaceURI(), samlElement.getLocalName()));
if (samlTokenValidator == null) {
samlTokenValidator = new SamlTokenValidatorImpl();
}
//important: check the signature before we do other processing...
if (samlAssertionWrapper.isSigned()) {
Signature signature = samlAssertionWrapper.getSignature();
if (signature == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN,
"empty", new Object[] {"no signature to validate"});
}
int sigKeyInfoIdx = getSignatureKeyInfoIndex(eventQueue);
if (sigKeyInfoIdx < 0) {
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "noKeyInSAMLToken");
}
InboundSecurityToken sigSecurityToken = parseKeyInfo(inputProcessorChain, securityProperties, eventQueue, sigKeyInfoIdx);
if (sigSecurityToken == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "noKeyInSAMLToken");
}
samlTokenValidator.validate(sigSecurityToken, wssSecurityProperties);
BasicCredential credential = null;
if (sigSecurityToken.getX509Certificates() != null) {
credential = new BasicX509Credential(sigSecurityToken.getX509Certificates()[0]);
} else if (sigSecurityToken.getPublicKey() != null) {
credential = new BasicCredential(sigSecurityToken.getPublicKey());
} else {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity",
new Object[] {"cannot get certificate or key"}
);
}
try {
SignatureValidator.validate(signature, credential);
} catch (SignatureException ex) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
ex, "empty", new Object[] {"SAML signature validation failed"});
}
}
final InboundSecurityToken subjectSecurityToken;
List<String> methods = samlAssertionWrapper.getConfirmationMethods();
boolean holderOfKey = false;
if (methods != null) {
for (String method : methods) {
if (OpenSAMLUtil.isMethodHolderOfKey(method)) {
holderOfKey = true;
break;
}
}
}
if (holderOfKey) {
int subjectKeyInfoIndex = getSubjectKeyInfoIndex(eventQueue);
if (subjectKeyInfoIndex < 0) {
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "noKeyInSAMLToken");
}
subjectSecurityToken = parseKeyInfo(inputProcessorChain, securityProperties, eventQueue, subjectKeyInfoIndex);
if (subjectSecurityToken == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "noKeyInSAMLToken");
}
} else {
subjectSecurityToken = null;
}
final List<XMLSecEvent> xmlSecEvents = getResponsibleXMLSecEvents(eventQueue, index);
final List<QName> elementPath = getElementPath(eventQueue);
final TokenContext tokenContext =
new TokenContext(wssSecurityProperties, wsInboundSecurityContext, xmlSecEvents, elementPath);
final SamlSecurityToken samlSecurityToken =
samlTokenValidator.validate(samlAssertionWrapper, subjectSecurityToken, tokenContext);
SecurityTokenProvider<InboundSecurityToken> subjectSecurityTokenProvider =
new SecurityTokenProvider<InboundSecurityToken>() {
@Override
public InboundSecurityToken getSecurityToken() throws XMLSecurityException {
return (InboundSecurityToken)samlSecurityToken;
}
@Override
public String getId() {
return samlAssertionWrapper.getId();
}
};
wsInboundSecurityContext.registerSecurityTokenProvider(samlAssertionWrapper.getId(), subjectSecurityTokenProvider);
//fire a tokenSecurityEvent
SamlTokenSecurityEvent samlTokenSecurityEvent = new SamlTokenSecurityEvent();
samlTokenSecurityEvent.setSecurityToken((SamlSecurityToken)subjectSecurityTokenProvider.getSecurityToken());
samlTokenSecurityEvent.setCorrelationID(samlAssertionWrapper.getId());
wsInboundSecurityContext.registerSecurityEvent(samlTokenSecurityEvent);
if (wssSecurityProperties.isValidateSamlSubjectConfirmation()) {
boolean soap12 = false;
if (elementPath.get(0) != null && WSSConstants.NS_SOAP12.equals(elementPath.get(0).getNamespaceURI())) {
soap12 = true;
}
SAMLTokenVerifierInputProcessor samlTokenVerifierInputProcessor =
new SAMLTokenVerifierInputProcessor(
securityProperties, samlAssertionWrapper, subjectSecurityTokenProvider, subjectSecurityToken,
soap12);
wsInboundSecurityContext.addSecurityEventListener(samlTokenVerifierInputProcessor);
inputProcessorChain.addProcessor(samlTokenVerifierInputProcessor);
}
}