/* * Copyright (c) 2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. 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.wso2.carbon.identity.sso.saml.admin; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.wso2.carbon.identity.application.common.util.IdentityApplicationManagementUtil; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.sso.saml.SAMLSSOConstants; import org.wso2.carbon.identity.sso.saml.SSOServiceProviderConfigManager; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; import java.util.ArrayList; import java.util.List; /** * This class reads the Service Providers info from sso-idp-config.xml and add them to the * in-memory service provider map exposed by org.wso2.carbon.identity.sso.saml. * SSOServiceProviderConfigManager class. */ public class FileBasedConfigManager { private static Log log = LogFactory.getLog(FileBasedConfigManager.class); private static volatile FileBasedConfigManager instance = null; private FileBasedConfigManager() { } public static FileBasedConfigManager getInstance() { if (instance == null) { synchronized (FileBasedConfigManager.class) { if (instance == null) { instance = new FileBasedConfigManager(); } } } return instance; } /** * Read the service providers from file, create SAMLSSOServiceProviderDO beans and add them * to the service providers map. */ public void addServiceProviders() { SAMLSSOServiceProviderDO[] serviceProviders = readServiceProvidersFromFile(); if (serviceProviders != null) { SSOServiceProviderConfigManager configManager = SSOServiceProviderConfigManager.getInstance(); for (SAMLSSOServiceProviderDO spDO : serviceProviders) { configManager.addServiceProvider(spDO.getIssuer(), spDO); log.info("A SSO Service Provider is registered for : " + spDO.getIssuer()); } } } /** * Read the SP info from the sso-idp-config.xml and create an array of SAMLSSOServiceProviderDO * beans * * @return An array of SAMLSSOServiceProviderDO beans */ private SAMLSSOServiceProviderDO[] readServiceProvidersFromFile() { Document document = null; try { String configFilePath = IdentityUtil.getIdentityConfigDirPath() + File.separator + "sso-idp-config.xml"; if (!isFileExisting(configFilePath)) { log.warn("sso-idp-config.xml does not exist in the "+IdentityUtil.getIdentityConfigDirPath() + " directory. The system may depend on the service providers added through the UI."); return new SAMLSSOServiceProviderDO[0]; } DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse(configFilePath); } catch (Exception e) { log.error("Error reading Service Providers from sso-idp-config.xml", e); return new SAMLSSOServiceProviderDO[0]; } Element element = document.getDocumentElement(); NodeList nodeSet = element.getElementsByTagName(SAMLSSOConstants.FileBasedSPConfig.SERVICE_PROVIDER); SAMLSSOServiceProviderDO[] serviceProviders = new SAMLSSOServiceProviderDO[nodeSet.getLength()]; boolean singleLogout = true; boolean signAssertion = true; boolean validateSignature = false; boolean encryptAssertion = false; String certAlias = null; for (int i = 0; i < nodeSet.getLength(); i++) { Element elem = (Element) nodeSet.item(i); SAMLSSOServiceProviderDO spDO = new SAMLSSOServiceProviderDO(); spDO.setIssuer(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.ISSUER)); List<String> assertionConsumerUrls = new ArrayList<>(); for(String assertionConsumerUrl : getTextValueList(elem, SAMLSSOConstants .FileBasedSPConfig.ASSERTION_CONSUMER_URL)) { assertionConsumerUrls.add(IdentityUtil.fillURLPlaceholders(assertionConsumerUrl.trim())); } spDO.setAssertionConsumerUrls(assertionConsumerUrls); spDO.setDefaultAssertionConsumerUrl(IdentityUtil .fillURLPlaceholders(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.DEFAULT_ACS_URL))); spDO.setLoginPageURL(IdentityUtil .fillURLPlaceholders(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.CUSTOM_LOGIN_PAGE))); if ((getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SINGLE_LOGOUT)) != null) { singleLogout = Boolean.valueOf(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SINGLE_LOGOUT)); spDO.setSloResponseURL(IdentityUtil .fillURLPlaceholders(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SLO_RESPONSE_URL))); spDO.setSloRequestURL(IdentityUtil .fillURLPlaceholders(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SLO_REQUEST_URL))); } if ((getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SIGN_ASSERTION)) != null) { signAssertion = Boolean.valueOf(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SIGN_ASSERTION)); } if ((getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SIG_VALIDATION)) != null) { validateSignature = Boolean.valueOf(getTextValue(elem, SAMLSSOConstants .FileBasedSPConfig.SIG_VALIDATION)); } if ((getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.ENCRYPT_ASSERTION)) != null) { encryptAssertion = Boolean.valueOf(getTextValue(elem, SAMLSSOConstants .FileBasedSPConfig.ENCRYPT_ASSERTION)); } if (getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SSO_DEFAULT_SIGNING_ALGORITHM) != null) { spDO.setSigningAlgorithmUri(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig .SSO_DEFAULT_SIGNING_ALGORITHM)); } else { spDO.setSigningAlgorithmUri(IdentityApplicationManagementUtil.getSigningAlgoURIByConfig()); } if (getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.SSO_DEFAULT_DIGEST_ALGORITHM) != null) { spDO.setDigestAlgorithmUri(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig .SSO_DEFAULT_DIGEST_ALGORITHM)); } else { spDO.setDigestAlgorithmUri(IdentityApplicationManagementUtil.getDigestAlgoURIByConfig()); } if (validateSignature || encryptAssertion) { certAlias = getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.CERT_ALIAS); if (certAlias == null) { log.warn("Certificate alias for Signature verification or Assertion encryption not specified. " + "Defaulting to \'wso2carbon\'"); certAlias = "wso2carbon"; } } if (Boolean.valueOf(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.ATTRIBUTE_PROFILE))) { spDO.setEnableAttributesByDefault(Boolean.valueOf(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.INCLUDE_ATTRIBUTE))); spDO.setAttributeConsumingServiceIndex(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.CONSUMING_SERVICE_INDEX)); } if (Boolean.valueOf(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.AUDIENCE_RESTRICTION)) && elem.getElementsByTagName(SAMLSSOConstants.FileBasedSPConfig.AUDIENCE_LIST) != null) { spDO.setRequestedAudiences(getTextValueList(elem, SAMLSSOConstants.FileBasedSPConfig.AUDIENCE)); } if (Boolean.valueOf(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.RECIPIENT_VALIDATION)) && elem.getElementsByTagName(SAMLSSOConstants.FileBasedSPConfig.RECIPIENT_LIST) != null) { spDO.setRequestedRecipients(getTextValueList(elem, SAMLSSOConstants.FileBasedSPConfig.RECIPIENT)); } if (Boolean.valueOf(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.ENABLE_IDP_INIT_SLO))) { spDO.setIdPInitSLOEnabled(true); if (elem.getElementsByTagName(SAMLSSOConstants.FileBasedSPConfig.RETURN_TO_URL_LIST) != null) { List<String> sloReturnToUrls = new ArrayList<>(); for(String sloReturnUrl : getTextValueList(elem, SAMLSSOConstants .FileBasedSPConfig.RETURN_TO_URL)) { sloReturnToUrls.add(IdentityUtil.fillURLPlaceholders(sloReturnUrl)); } spDO.setIdpInitSLOReturnToURLs(sloReturnToUrls); } } spDO.setDoSingleLogout(singleLogout); spDO.setDoSignAssertions(signAssertion); spDO.setDoValidateSignatureInRequests(validateSignature); spDO.setDoEnableEncryptedAssertion(encryptAssertion); spDO.setDoSignResponse(Boolean.valueOf(getTextValue(elem, SAMLSSOConstants .FileBasedSPConfig.SIGN_RESPONSE))); spDO.setCertAlias(certAlias); spDO.setIdPInitSSOEnabled(Boolean.valueOf(getTextValue(elem, SAMLSSOConstants.FileBasedSPConfig.IDP_INIT))); serviceProviders[i] = spDO; } return serviceProviders; } /** * Read the element value for the given element * * @param element Parent element * @param tagName name of the child element * @return value of the element */ private String getTextValue(Element element, String tagName) { String textVal = null; NodeList nl = element.getElementsByTagName(tagName); if (nl != null && nl.getLength() > 0) { Element el = (Element) nl.item(0); if (el != null) { String text = el.getTextContent(); if (text != null && text.length() > 0) { textVal = text; } } } return textVal; } private List<String> getTextValueList(Element element, String tagName) { List<String> textValList = new ArrayList<>(); NodeList nl = element.getElementsByTagName(tagName); if (nl != null && nl.getLength() > 0) { for (int i = 0; i < nl.getLength(); i++) { Element el = (Element) nl.item(i); if (el != null) { String text = el.getTextContent(); if (text != null && text.length() > 0) { textValList.add(text); } } } } return textValList; } /** * Check whether a given file exists in the system * * @param path file path * @return true, if file exists. False otherwise */ private boolean isFileExisting(String path) { File file = new File(path); if (file.exists()) { return true; } return false; } }