org.picketlink.config.federation.parsers.STSConfigParser Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.picketlink.config.federation.parsers;
import org.picketlink.common.ErrorCodes;
import org.picketlink.common.exceptions.ParsingException;
import org.picketlink.common.parsers.AbstractParser;
import org.picketlink.common.util.StaxParserUtil;
import org.picketlink.config.federation.AuthPropertyType;
import org.picketlink.config.federation.ClaimsProcessorType;
import org.picketlink.config.federation.ClaimsProcessorsType;
import org.picketlink.config.federation.KeyProviderType;
import org.picketlink.config.federation.KeyValueType;
import org.picketlink.config.federation.STSType;
import org.picketlink.config.federation.ServiceProviderType;
import org.picketlink.config.federation.ServiceProvidersType;
import org.picketlink.config.federation.TokenProviderType;
import org.picketlink.config.federation.TokenProvidersType;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
/**
*
* A Stax parser for the STS configuration.
*
*
* @author Stefan Guilhen
*/
public class STSConfigParser extends AbstractParser {
private static final String CONFIG_NS = "urn:picketlink:identity-federation:config:1.0";
// XML configuration elements.
public static final String ROOT_ELEMENT = "PicketLinkSTS";
private static final String KEY_PROVIDER_ELEMENT = "KeyProvider";
private static final String AUTH_ELEMENT = "Auth";
private static final String SIGNING_ALIAS_ELEMENT = "SigningAlias";
private static final String VALIDATING_ALIAS_ELEMENT = "ValidatingAlias";
private static final String REQUEST_HANDLER_ELEMENT = "RequestHandler";
private static final String PROPERTY_ELEMENT = "Property";
private static final String CLAIMS_PROCESSORS_ELEMENT = "ClaimsProcessors";
private static final String CLAIMS_PROCESSOR_ELEMENT = "ClaimsProcessor";
private static final String TOKEN_PROVIDERS_ELEMENT = "TokenProviders";
private static final String TOKEN_PROVIDER_ELEMENT = "TokenProvider";
private static final String SERVICE_PROVIDERS_ELEMENT = "ServiceProviders";
private static final String SERVICE_PROVIDER_ELEMENT = "ServiceProvider";
// XML configuration attributes.
private static final String STS_NAME_ATTRIB = "STSName";
private static final String TOKEN_TIMEOUT_ATTRIB = "TokenTimeout";
private static final String CLOCK_SKEW_ATTRIB = "ClockSkew";
private static final String SIGN_TOKEN_ATTRIB = "SignToken";
private static final String ENCRYPT_TOKEN_ATTRIB = "EncryptToken";
private static final String CANON_METHOD_ATTRIB = "CanonicalizationMethod";
private static final String CLASS_NAME_ATTRIB = "ClassName";
private static final String KEY_ATTRIB = "Key";
private static final String VALUE_ATTRIB = "Value";
private static final String DIALECT_ATTRIB = "Dialect";
private static final String PROCESSOR_CLASS_ATTRIB = "ProcessorClass";
private static final String PROVIDER_CLASS_ATTRIB = "ProviderClass";
private static final String TOKEN_TYPE_ATTRIB = "TokenType";
private static final String TOKEN_ELEMENT_ATTRIB = "TokenElement";
private static final String TOKEN_ELEMENT_NS_ATTRIB = "TokenElementNS";
private static final String ENDPOINT_ATTRIB = "Endpoint";
private static final String ENDPOINT_REGEX_ATTRIB = "EndpointRegEx";
private static final String TRUSTSTORE_ALIAS_ATTRIB = "TruststoreAlias";
/*
* (non-Javadoc)
*
* @see org.picketlink.identity.federation.core.parsers.ParserNamespaceSupport#parse(javax.xml.stream.XMLEventReader)
*/
public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
StaxParserUtil.validate(startElement, ROOT_ELEMENT);
STSType configType = new STSType();
// parse and set the root element attributes.
QName attributeQName = new QName("", STS_NAME_ATTRIB);
Attribute attribute = startElement.getAttributeByName(attributeQName);
if (attribute != null)
configType.setSTSName(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", TOKEN_TIMEOUT_ATTRIB);
attribute = startElement.getAttributeByName(attributeQName);
if (attribute != null)
configType.setTokenTimeout(Integer.valueOf(StaxParserUtil.getAttributeValue(attribute)));
attributeQName = new QName("", CLOCK_SKEW_ATTRIB);
attribute = startElement.getAttributeByName(attributeQName);
if (attribute != null)
configType.setClockSkew(Integer.valueOf(StaxParserUtil.getAttributeValue(attribute)));
attributeQName = new QName("", SIGN_TOKEN_ATTRIB);
attribute = startElement.getAttributeByName(attributeQName);
if (attribute != null)
configType.setSignToken(Boolean.valueOf(StaxParserUtil.getAttributeValue(attribute)));
attributeQName = new QName("", ENCRYPT_TOKEN_ATTRIB);
attribute = startElement.getAttributeByName(attributeQName);
if (attribute != null)
configType.setEncryptToken(Boolean.valueOf(StaxParserUtil.getAttributeValue(attribute)));
attributeQName = new QName("", CANON_METHOD_ATTRIB);
attribute = startElement.getAttributeByName(attributeQName);
if (attribute != null)
configType.setCanonicalizationMethod(StaxParserUtil.getAttributeValue(attribute));
// parse the inner elements.
while (xmlEventReader.hasNext()) {
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
if (xmlEvent == null)
break;
if (xmlEvent instanceof EndElement) {
EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
String endElementName = StaxParserUtil.getEndElementName(endElement);
if (endElementName.equals(ROOT_ELEMENT))
break;
else
throw logger.parserUnknownEndElement(endElementName);
}
StartElement subEvent = StaxParserUtil.peekNextStartElement(xmlEventReader);
if (subEvent == null)
break;
String elementName = StaxParserUtil.getStartElementName(subEvent);
if (KEY_PROVIDER_ELEMENT.equalsIgnoreCase(elementName)) {
configType.setKeyProvider(this.parseKeyProvider(xmlEventReader));
} else if (REQUEST_HANDLER_ELEMENT.equalsIgnoreCase(elementName)) {
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
if (!StaxParserUtil.hasTextAhead(xmlEventReader))
throw new ParsingException(ErrorCodes.EXPECTED_TEXT_VALUE + "RequestHandler");
configType.setRequestHandler(StaxParserUtil.getElementText(xmlEventReader));
} else if (CLAIMS_PROCESSORS_ELEMENT.equalsIgnoreCase(elementName)) {
configType.setClaimsProcessors(this.parseClaimsProcessors(xmlEventReader));
} else if (TOKEN_PROVIDERS_ELEMENT.equalsIgnoreCase(elementName)) {
configType.setTokenProviders(this.parseTokenProviders(xmlEventReader));
} else if (SERVICE_PROVIDERS_ELEMENT.equalsIgnoreCase(elementName)) {
configType.setServiceProviders(this.parseServiceProviders(xmlEventReader));
} else
throw logger.parserUnknownTag(elementName, subEvent.getLocation());
}
return configType;
}
/*
* (non-Javadoc)
*
* @see org.picketlink.identity.federation.core.parsers.ParserNamespaceSupport#supports(javax.xml.namespace.QName)
*/
public boolean supports(QName qname) {
return CONFIG_NS.equals(qname.getNamespaceURI());
}
/**
*
* Parses the {@code KeyProvider} section of the STS configuration file. This section is used to setup the keystore \ that
* will be used to sign and encrypt security tokens.
*
*
* @param xmlEventReader the reader used to parse the XML configuration file.
* @return a {@code KeyProviderType} instance that contains the parsed data.
* @throws ParsingException if an error occurs while parsing the XML file.
*/
private KeyProviderType parseKeyProvider(XMLEventReader xmlEventReader) throws ParsingException {
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
StaxParserUtil.validate(startElement, KEY_PROVIDER_ELEMENT);
KeyProviderType keyProvider = new KeyProviderType();
// get the key provider class name attribute.
QName attributeQName = new QName("", CLASS_NAME_ATTRIB);
Attribute attribute = startElement.getAttributeByName(attributeQName);
if (attribute == null)
throw logger.parserRequiredAttribute("ClassName");
keyProvider.setClassName(StaxParserUtil.getAttributeValue(attribute));
// parse the inner elements.
while (xmlEventReader.hasNext()) {
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
if (xmlEvent == null)
break;
if (xmlEvent instanceof EndElement) {
EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
String endElementName = StaxParserUtil.getEndElementName(endElement);
if (endElementName.equals(KEY_PROVIDER_ELEMENT))
break;
else
throw logger.parserUnknownEndElement(endElementName);
}
StartElement subEvent = StaxParserUtil.peekNextStartElement(xmlEventReader);
if (subEvent == null)
break;
String elementName = StaxParserUtil.getStartElementName(subEvent);
if (SIGNING_ALIAS_ELEMENT.equalsIgnoreCase(elementName)) {
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
if (!StaxParserUtil.hasTextAhead(xmlEventReader))
throw logger.parserExpectedTextValue("SigningAlias");
keyProvider.setSigningAlias(StaxParserUtil.getElementText(xmlEventReader));
} else if (VALIDATING_ALIAS_ELEMENT.equalsIgnoreCase(elementName)) {
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
KeyValueType keyValue = new KeyValueType();
// parse the key and value attributes.
attributeQName = new QName("", KEY_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
keyValue.setKey(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", VALUE_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
keyValue.setValue(StaxParserUtil.getAttributeValue(attribute));
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
StaxParserUtil.validate(endElement, VALIDATING_ALIAS_ELEMENT);
keyProvider.add(keyValue);
} else if (AUTH_ELEMENT.equalsIgnoreCase(elementName)) {
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
AuthPropertyType authProperty = new AuthPropertyType();
// parse the key and value attributes.
attributeQName = new QName("", KEY_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
authProperty.setKey(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", VALUE_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
authProperty.setValue(StaxParserUtil.getAttributeValue(attribute));
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
StaxParserUtil.validate(endElement, AUTH_ELEMENT);
keyProvider.add(authProperty);
} else
throw logger.parserUnknownTag(elementName, subEvent.getLocation());
}
return keyProvider;
}
/**
*
* Parses the {@code ClaimsProcessors} section of the STS configuration file.
*
*
* @param xmlEventReader the reader used to parse the XML configuration file.
* @return a {@code ClaimsProcessorsType} instance that contains the parsed data.
* @throws ParsingException if an error occurs while parsing the XML file.
*/
private ClaimsProcessorsType parseClaimsProcessors(XMLEventReader xmlEventReader) throws ParsingException {
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
StaxParserUtil.validate(startElement, CLAIMS_PROCESSORS_ELEMENT);
ClaimsProcessorsType claimsProcessors = new ClaimsProcessorsType();
// parse all claims processors one by one.
while (xmlEventReader.hasNext()) {
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
if (xmlEvent == null)
break;
if (xmlEvent instanceof EndElement) {
EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
String endElementName = StaxParserUtil.getEndElementName(endElement);
if (endElementName.equals(CLAIMS_PROCESSORS_ELEMENT))
break;
else
throw logger.parserUnknownEndElement(endElementName);
}
StartElement subEvent = StaxParserUtil.peekNextStartElement(xmlEventReader);
if (subEvent == null)
break;
String elementName = StaxParserUtil.getStartElementName(subEvent);
if (CLAIMS_PROCESSOR_ELEMENT.equalsIgnoreCase(elementName)) {
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
StaxParserUtil.validate(subEvent, CLAIMS_PROCESSOR_ELEMENT);
ClaimsProcessorType claimsProcessor = new ClaimsProcessorType();
// parse the processor attributes (class and dialect).
QName attributeQName = new QName("", PROCESSOR_CLASS_ATTRIB);
Attribute attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
claimsProcessor.setProcessorClass(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", DIALECT_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
claimsProcessor.setDialect(StaxParserUtil.getAttributeValue(attribute));
// parse the processor properties.
while (xmlEventReader.hasNext()) {
xmlEvent = StaxParserUtil.peek(xmlEventReader);
if (xmlEvent == null)
break;
if (xmlEvent instanceof EndElement) {
EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
String endElementName = StaxParserUtil.getEndElementName(endElement);
if (endElementName.equals(CLAIMS_PROCESSOR_ELEMENT))
break;
else
throw logger.parserUnknownEndElement(endElementName);
}
subEvent = StaxParserUtil.peekNextStartElement(xmlEventReader);
if (subEvent == null)
break;
elementName = StaxParserUtil.getStartElementName(subEvent);
if (PROPERTY_ELEMENT.equalsIgnoreCase(elementName)) {
// parse the property key and value.
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
KeyValueType keyValue = new KeyValueType();
// parse the key and value attributes.
attributeQName = new QName("", KEY_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
keyValue.setKey(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", VALUE_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
keyValue.setValue(StaxParserUtil.getAttributeValue(attribute));
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
StaxParserUtil.validate(endElement, PROPERTY_ELEMENT);
claimsProcessor.add(keyValue);
} else
throw logger.parserUnknownTag(elementName, subEvent.getLocation());
}
claimsProcessors.add(claimsProcessor);
} else
throw logger.parserUnknownTag(elementName, subEvent.getLocation());
}
return claimsProcessors;
}
/**
*
* Parses the {@code TokenProviders} section of the STS configuration file.
*
*
* @param xmlEventReader the reader used to parse the XML configuration file.
* @return a {@code TokenProvidersType} instance that contains the parsed data.
* @throws ParsingException if an error occurs while parsing the XML file.
*/
private TokenProvidersType parseTokenProviders(XMLEventReader xmlEventReader) throws ParsingException {
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
StaxParserUtil.validate(startElement, TOKEN_PROVIDERS_ELEMENT);
TokenProvidersType tokenProviders = new TokenProvidersType();
// parse all token providers one by one.
while (xmlEventReader.hasNext()) {
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
if (xmlEvent == null)
break;
if (xmlEvent instanceof EndElement) {
EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
String endElementName = StaxParserUtil.getEndElementName(endElement);
if (endElementName.equals(TOKEN_PROVIDERS_ELEMENT))
break;
else
throw logger.parserUnknownEndElement(endElementName);
}
StartElement subEvent = StaxParserUtil.peekNextStartElement(xmlEventReader);
if (subEvent == null)
break;
String elementName = StaxParserUtil.getStartElementName(subEvent);
if (TOKEN_PROVIDER_ELEMENT.equalsIgnoreCase(elementName)) {
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
StaxParserUtil.validate(subEvent, TOKEN_PROVIDER_ELEMENT);
TokenProviderType tokenProvider = new TokenProviderType();
// parse the provider attributes (provider class, token type, token element, token namespace).
QName attributeQName = new QName("", PROVIDER_CLASS_ATTRIB);
Attribute attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
tokenProvider.setProviderClass(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", TOKEN_TYPE_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
tokenProvider.setTokenType(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", TOKEN_ELEMENT_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
tokenProvider.setTokenElement(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", TOKEN_ELEMENT_NS_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
tokenProvider.setTokenElementNS(StaxParserUtil.getAttributeValue(attribute));
// parse the provider properties.
while (xmlEventReader.hasNext()) {
xmlEvent = StaxParserUtil.peek(xmlEventReader);
if (xmlEvent == null)
break;
if (xmlEvent instanceof EndElement) {
EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
String endElementName = StaxParserUtil.getEndElementName(endElement);
if (endElementName.equals(TOKEN_PROVIDER_ELEMENT))
break;
else
throw logger.parserUnknownEndElement(endElementName);
}
subEvent = StaxParserUtil.peekNextStartElement(xmlEventReader);
if (subEvent == null)
break;
elementName = StaxParserUtil.getStartElementName(subEvent);
if (PROPERTY_ELEMENT.equalsIgnoreCase(elementName)) {
// parse the property key and value.
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
KeyValueType keyValue = new KeyValueType();
// parse the key and value attributes.
attributeQName = new QName("", KEY_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
keyValue.setKey(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", VALUE_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
keyValue.setValue(StaxParserUtil.getAttributeValue(attribute));
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
StaxParserUtil.validate(endElement, PROPERTY_ELEMENT);
tokenProvider.add(keyValue);
} else
throw logger.parserUnknownTag(elementName, subEvent.getLocation());
}
tokenProviders.add(tokenProvider);
} else
throw logger.parserUnknownTag(elementName, subEvent.getLocation());
}
return tokenProviders;
}
/**
*
* Parses the {@code ServiceProviders} section of the STS configuration file.
*
*
* @param xmlEventReader the reader used to parse the XML configuration file.
* @return a {@code ServiceProvidersType} instance that contains the parsed data.
* @throws ParsingException if an error occurs while parsing the XML file.
*/
private ServiceProvidersType parseServiceProviders(XMLEventReader xmlEventReader) throws ParsingException {
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
StaxParserUtil.validate(startElement, SERVICE_PROVIDERS_ELEMENT);
ServiceProvidersType serviceProviders = new ServiceProvidersType();
// parse all token providers one by one.
while (xmlEventReader.hasNext()) {
XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
if (xmlEvent == null)
break;
if (xmlEvent instanceof EndElement) {
EndElement endElement = (EndElement) StaxParserUtil.getNextEvent(xmlEventReader);
String endElementName = StaxParserUtil.getEndElementName(endElement);
if (endElementName.equals(SERVICE_PROVIDERS_ELEMENT))
break;
else
throw logger.parserUnknownEndElement(endElementName);
}
StartElement subEvent = StaxParserUtil.peekNextStartElement(xmlEventReader);
if (subEvent == null)
break;
String elementName = StaxParserUtil.getStartElementName(subEvent);
if (SERVICE_PROVIDER_ELEMENT.equalsIgnoreCase(elementName)) {
subEvent = StaxParserUtil.getNextStartElement(xmlEventReader);
StaxParserUtil.validate(subEvent, SERVICE_PROVIDER_ELEMENT);
ServiceProviderType serviceProvider = new ServiceProviderType();
// parse the provider attributes (endpoint, token type and truststore alias).
QName attributeQName = new QName("", TOKEN_TYPE_ATTRIB);
Attribute attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
serviceProvider.setTokenType(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", ENDPOINT_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
serviceProvider.setEndpoint(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", ENDPOINT_REGEX_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
serviceProvider.setEndpointRegEx(StaxParserUtil.getAttributeValue(attribute));
attributeQName = new QName("", TRUSTSTORE_ALIAS_ATTRIB);
attribute = subEvent.getAttributeByName(attributeQName);
if (attribute != null)
serviceProvider.setTruststoreAlias(StaxParserUtil.getAttributeValue(attribute));
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
StaxParserUtil.validate(endElement, SERVICE_PROVIDER_ELEMENT);
serviceProviders.add(serviceProvider);
} else
throw logger.parserUnknownTag(elementName, subEvent.getLocation());
}
return serviceProviders;
}
}