diff --git a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/security/AuthenticatorsConfiguration.java b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/security/AuthenticatorsConfiguration.java index f3b5ecf153f..a096969da50 100644 --- a/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/security/AuthenticatorsConfiguration.java +++ b/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/security/AuthenticatorsConfiguration.java @@ -78,16 +78,26 @@ public static class AuthenticatorConfig { private Map parameters = new Hashtable(); + private final Map> parameterMap; + private List authenticationSkippingUrls = new ArrayList(); private List sessionValidationSkippingUrls = new ArrayList(); private AuthenticatorConfig(String name, int priority, boolean disabled, Map params) { + String> params, Map> paramMap) { this.name = name; this.priority = priority; this.disabled = disabled; this.parameters = params; + + // Make sure that outer map and inner maps are unmodifiable. + Map> unmodifiableParamMap = new HashMap<>(); + for (Map.Entry> entry : paramMap.entrySet()) { + unmodifiableParamMap.put(entry.getKey(), + Collections.unmodifiableMap(new HashMap<>(entry.getValue()))); + } + this.parameterMap = Collections.unmodifiableMap(unmodifiableParamMap); } public String getName() { @@ -106,6 +116,14 @@ public Map getParameters() { return parameters; } + public Map> getParameterMap() { + return parameterMap; + } + + public Map getConfigFromParameterMap(String configName) { + return parameterMap.get(configName); + } + public void addAuthenticationSkippingUrl(String url) { this.authenticationSkippingUrls.add(url); } @@ -178,62 +196,99 @@ private void initialize() { } /** - * Create AuthenticatorConfig elements for each authenticator entry - * @param authenticatorElem OMElement for Authenticator - * @return AuthenticatorConfig object + * Create AuthenticatorConfig elements for each authenticator entry. + * + * @param authenticatorElem OMElement for Authenticator. + * @return AuthenticatorConfig object. */ private AuthenticatorConfig processAuthenticatorElement(OMElement authenticatorElem) { // read the name of the authenticator. this is a mandatory attribute. OMAttribute nameAttr = authenticatorElem.getAttribute(new QName(ATTR_NAME)); // if the name is not given, do not register this authenticator - if(nameAttr == null){ + if (nameAttr == null) { log.warn("Each Authenticator Configuration should have a unique name attribute. +" + - "This Authenticator will not be registered."); + "This Authenticator will not be registered."); return null; } String authenticatorName = nameAttr.getAttributeValue(); // check whether the disabled attribute is set boolean disabled = false; - if(authenticatorElem.getAttribute(new QName(ATTR_DISABLED)) != null){ + if (authenticatorElem.getAttribute(new QName(ATTR_DISABLED)) != null) { disabled = Boolean.parseBoolean(authenticatorElem.getAttribute( new QName(ATTR_DISABLED)).getAttributeValue()); } // read the priority int priority = 0; - for(Iterator priorityElemItr = authenticatorElem.getChildrenWithLocalName(ELEM_PRIORITY); - priorityElemItr.hasNext();){ - priority = Integer.parseInt(((OMElement)priorityElemItr.next()).getText()); + for (Iterator priorityElemItr = authenticatorElem.getChildrenWithLocalName(ELEM_PRIORITY); + priorityElemItr.hasNext(); ) { + priority = Integer.parseInt(((OMElement) priorityElemItr.next()).getText()); } // read the config parameters - Map parameterMap = new Hashtable(); - for(Iterator configElemItr = authenticatorElem.getChildrenWithLocalName(ELEM_CONFIG); - configElemItr.hasNext();){ - OMElement configElement = (OMElement)configElemItr.next(); - for(Iterator paramIterator = configElement.getChildrenWithLocalName(ELEM_PARAMETER); - paramIterator.hasNext();){ - OMElement paramElem = (OMElement)paramIterator.next(); + Map parameterMap = new Hashtable<>(); + Map> nestedParameterMap = new HashMap<>(); + + for (Iterator configElemItr = authenticatorElem.getChildrenWithLocalName(ELEM_CONFIG); + configElemItr.hasNext(); ) { + OMElement configElement = (OMElement) configElemItr.next(); + + // Only process configs that have an explicit name attribute. + OMAttribute configNameAttr = configElement.getAttribute(new QName(ATTR_NAME)); + if (configNameAttr == null) { + // Skip configs without name attribute - process parameters for flat map only. + for (Iterator paramIterator = configElement.getChildrenWithLocalName(ELEM_PARAMETER); + paramIterator.hasNext(); ) { + OMElement paramElem = (OMElement) paramIterator.next(); + OMAttribute paramNameAttr = paramElem.getAttribute(new QName(ATTR_NAME)); + if (paramNameAttr == null) { + log.warn("An Authenticator Parameter should have a name attribute. Skipping the parameter."); + continue; + } + // Add to flat map for backward compatibility. + parameterMap.put(paramNameAttr.getAttributeValue(), paramElem.getText()); + } + continue; + } + + String configName = configNameAttr.getAttributeValue(); + + // Create a map for this config's parameters. + Map configParametersMap = new HashMap<>(); + + for (Iterator paramIterator = configElement.getChildrenWithLocalName(ELEM_PARAMETER); + paramIterator.hasNext(); ) { + OMElement paramElem = (OMElement) paramIterator.next(); OMAttribute paramNameAttr = paramElem.getAttribute(new QName(ATTR_NAME)); - if(paramNameAttr == null){ + if (paramNameAttr == null) { log.warn("An Authenticator Parameter should have a name attribute. Skipping the parameter."); continue; } - parameterMap.put(paramNameAttr.getAttributeValue(), paramElem.getText()); + String paramName = paramNameAttr.getAttributeValue(); + String paramValue = paramElem.getText(); + + // Add to both the flat map (for backward compatibility) and the nested map. + parameterMap.put(paramName, paramValue); + configParametersMap.put(paramName, paramValue); + } + + // Add the config parameters to the nested parameterMap if it has any parameters. + if (!configParametersMap.isEmpty()) { + nestedParameterMap.put(configName, configParametersMap); } } AuthenticatorConfig authenticatorConfig = new AuthenticatorConfig(authenticatorName, - priority, disabled, parameterMap); + priority, disabled, parameterMap, nestedParameterMap); // read authentication skipping urls - for(Iterator configElemItr = authenticatorElem.getChildrenWithLocalName(ELEM_SKIP_AUTHENTICATION); - configElemItr.hasNext();){ - OMElement configElement = (OMElement)configElemItr.next(); - for(Iterator paramIterator = configElement.getChildrenWithLocalName(ELEM_URL_CONTAINS); - paramIterator.hasNext();){ - OMElement urlElement = (OMElement)paramIterator.next(); + for (Iterator configElemItr = authenticatorElem.getChildrenWithLocalName(ELEM_SKIP_AUTHENTICATION); + configElemItr.hasNext(); ) { + OMElement configElement = (OMElement) configElemItr.next(); + for (Iterator paramIterator = configElement.getChildrenWithLocalName(ELEM_URL_CONTAINS); + paramIterator.hasNext(); ) { + OMElement urlElement = (OMElement) paramIterator.next(); if (urlElement.getText() != null && !urlElement.getText().isEmpty()) { authenticatorConfig.addAuthenticationSkippingUrl(urlElement.getText().trim()); @@ -242,12 +297,12 @@ private AuthenticatorConfig processAuthenticatorElement(OMElement authenticatorE } // read session validation skipping urls - for(Iterator configElemItr = authenticatorElem.getChildrenWithLocalName(ELEM_SKIP_SESSION_VALIDATION); - configElemItr.hasNext();){ - OMElement configElement = (OMElement)configElemItr.next(); - for(Iterator paramIterator = configElement.getChildrenWithLocalName(ELEM_URL_CONTAINS); - paramIterator.hasNext();){ - OMElement urlElement = (OMElement)paramIterator.next(); + for (Iterator configElemItr = authenticatorElem.getChildrenWithLocalName(ELEM_SKIP_SESSION_VALIDATION); + configElemItr.hasNext(); ) { + OMElement configElement = (OMElement) configElemItr.next(); + for (Iterator paramIterator = configElement.getChildrenWithLocalName(ELEM_URL_CONTAINS); + paramIterator.hasNext(); ) { + OMElement urlElement = (OMElement) paramIterator.next(); if (urlElement.getText() != null && !urlElement.getText().isEmpty()) { authenticatorConfig.addSessionValidationSkippingUrl(urlElement.getText().trim()); diff --git a/distribution/kernel/carbon-home/repository/resources/conf/templates/repository/conf/security/authenticators.xml.j2 b/distribution/kernel/carbon-home/repository/resources/conf/templates/repository/conf/security/authenticators.xml.j2 index 139d598c8dc..54eea29557f 100644 --- a/distribution/kernel/carbon-home/repository/resources/conf/templates/repository/conf/security/authenticators.xml.j2 +++ b/distribution/kernel/carbon-home/repository/resources/conf/templates/repository/conf/security/authenticators.xml.j2 @@ -67,8 +67,19 @@ {% for key,value in admin_console.authenticator.mutual_ssl_authenticator.config.items() %} {{value}} {% endfor %} - - + + + + {% if admin_console.authenticator.mutual_ssl_authenticator.named_configs is defined %} + {% for config_name, config_params in admin_console.authenticator.mutual_ssl_authenticator.named_configs.items() %} + + {% for key, value in config_params.items() %} + {{value}} + {% endfor %} + + {% endfor %} + {% endif %} + {% if admin_console.authenticator.iwa_ui_authenticator is defined %}