/**
* Copyright 2015-2017 Red Hat, Inc, and individual contributors.
*
* 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.wildfly.swarm.undertow.runtime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.enterprise.context.ApplicationScoped;
import org.jboss.logging.Logger;
import org.jboss.shrinkwrap.api.Archive;
import org.wildfly.swarm.config.runtime.AttributeDocumentation;
import org.wildfly.swarm.spi.api.ArchivePreparer;
import org.wildfly.swarm.spi.api.annotations.Configurable;
import org.wildfly.swarm.undertow.WARArchive;
import org.wildfly.swarm.undertow.descriptors.JBossWebAsset;
import org.wildfly.swarm.undertow.descriptors.SecurityConstraint;
import org.wildfly.swarm.undertow.descriptors.WebXmlAsset;
/**
* @author Heiko Braun
* @author Ken Finnigan
*/
@ApplicationScoped
public class HttpSecurityPreparer implements ArchivePreparer {
private static final Logger LOG = Logger.getLogger(HttpSecurityPreparer.class);
private final String[] SUPPORTED_AUTH_METHODS = new String[] {"BASIC", "DIGEST", "FORM", "KEYCLOAK"};
@SuppressWarnings("unchecked")
@Override
public void prepareArchive(Archive<?> archive) {
if (deploymentConfigs == null || deploymentConfigs.isEmpty()) {
return;
}
// find a matching archive declaration
Optional<String> match = deploymentConfigs.keySet()
.stream()
.filter(c -> archive.getName().equals(c))
.findFirst();
if (!match.isPresent()) {
return; // no matching archive
}
Map<String, Object> matchingConfig = (Map<String, Object>) deploymentConfigs.get(match.get());
if (!matchingConfig.containsKey("web")) {
return; // missing web configuration
}
Map<String, Object> deploymentConfig = (Map<String, Object>) matchingConfig.get("web");
WARArchive war = archive.as(WARArchive.class);
WebXmlAsset webXml = war.findWebXmlAsset();
JBossWebAsset jbossWeb = war.findJbossWebAsset();
// unsupported auth method
Map<String, Object> loginConfig = (Map<String, Object>) deploymentConfig.get("login-config");
if (loginConfig != null) {
String authMethod = (String)loginConfig.getOrDefault("auth-method", "NONE");
boolean isSupported = false;
for (String supported : SUPPORTED_AUTH_METHODS) {
if (authMethod.equals(supported)) {
isSupported = true;
break;
}
}
if (!isSupported) {
LOG.warn("Ignoring unsupported auth-method: " + authMethod);
return;
}
// Setup login-config
webXml.setLoginConfig(authMethod, "ignored");
// security domain
if (loginConfig.containsKey("security-domain")) {
jbossWeb.setSecurityDomain((String)loginConfig.get("security-domain"));
}
// form login
if (loginConfig.containsKey("form-login-config")) {
Map<String, Object> formLoginConfig = (Map<String, Object>) loginConfig.get("form-login-config");
webXml.setFormLoginConfig(
"Security Realm",
(String)formLoginConfig.get("form-login-page"),
(String)formLoginConfig.get("form-error-page")
);
}
}
// security constraints
List<Map<String, Object>> securityConstraints =
(List<Map<String, Object>>) deploymentConfig.getOrDefault("security-constraints", Collections.EMPTY_LIST);
for (Map<String, Object> sc : securityConstraints) {
SecurityConstraint securityConstraint = webXml
.protect((String) sc.getOrDefault("url-pattern", "/*"));
((List<String>) sc.getOrDefault("methods", Collections.emptyList()))
.forEach(securityConstraint::withMethod);
((List<String>) sc.getOrDefault("roles", Collections.emptyList()))
.forEach(securityConstraint::withRole);
}
}
@AttributeDocumentation("Map of security configuration by deployment")
@Configurable("swarm.deployment")
Map<String, Object> deploymentConfigs;
}