Search in sources :

Example 1 with SecurityConstraint

use of org.wildfly.swarm.undertow.descriptors.SecurityConstraint in project wildfly-swarm by wildfly-swarm.

the class MPJWTAuthExtensionArchivePreparer method generateSecurityConstraints.

/**
 * Generate security constraints for a resource root class.
 *
 * @param webXml - the deployment web.xml metadata to add the security constraints to
 * @param classInfo - the class to scan for security constraints
 * @param roles - class level roles if any
 * @param appPath - the @ApplicationPath if any
 */
private void generateSecurityConstraints(WebXmlAsset webXml, ClassInfo classInfo, String[] roles, final String appPath) {
    // This includes both class level and method level @Path instances
    List<AnnotationInstance> paths = classInfo.annotations().get(PATH);
    if (paths == null || paths.size() == 0) {
        // Not a resource root
        return;
    }
    StringBuilder fullAppPath = new StringBuilder(appPath);
    if (fullAppPath.charAt(fullAppPath.length() - 1) != '/') {
        fullAppPath.append('/');
    }
    List<SecurityConstraint> newConstraints = new ArrayList<>();
    HashSet<String> allRoles = new HashSet<>();
    allRoles.addAll(Arrays.asList(roles));
    // Get the root @Path annotation if it exists
    ListIterator<AnnotationInstance> pathsIter = paths.listIterator();
    while (pathsIter.hasNext()) {
        AnnotationInstance ann = pathsIter.next();
        if (ann.target().kind() == AnnotationTarget.Kind.CLASS) {
            String subpath = ann.value().asString();
            if (subpath.charAt(0) == '/') {
                fullAppPath.append(subpath.substring(1));
            } else {
                fullAppPath.append(subpath);
            }
            if (fullAppPath.charAt(fullAppPath.length() - 1) != '/') {
                fullAppPath.append('/');
            }
            pathsIter.remove();
            break;
        }
    }
    // Check for a class level @DenyAll
    boolean classIsDenyAll = false;
    boolean classIsPermitAll = false;
    List<AnnotationInstance> classDenyAll = classInfo.annotations().get(DENY_ALL);
    if (classDenyAll != null) {
        for (AnnotationInstance ann : classDenyAll) {
            if (ann.target() == classInfo) {
                // Create a security constraint that denies all access to subresources by default
                SecurityConstraint sc = webXml.protect(fullAppPath.toString() + "*").withRole("");
                newConstraints.add(sc);
                classIsDenyAll = true;
            }
        }
    }
    // Check for class level @PermitAll
    List<AnnotationInstance> classPermitAll = classInfo.annotations().get(PERMIT_ALL);
    if (classPermitAll != null) {
        for (AnnotationInstance ann : classPermitAll) {
            if (ann.target() == classInfo) {
                // Create a security constraint that permits all access to subresources by default
                SecurityConstraint sc = webXml.protect(fullAppPath.toString() + "*").permitAll();
                newConstraints.add(sc);
                classIsPermitAll = true;
            }
        }
    }
    // Process the method level @Path and security annotations into security constraints
    for (AnnotationInstance path : paths) {
        if (path.target().kind() == AnnotationTarget.Kind.METHOD) {
            // For each method determine the endpoint path and roles
            String subpath = path.value().asString();
            MethodInfo methodInfo = path.target().asMethod();
            AnnotationInstance rolesAllowed = methodInfo.annotation(ROLES_ALLOWED);
            AnnotationInstance denyAll = methodInfo.annotation(DENY_ALL);
            AnnotationInstance permitAll = methodInfo.annotation(PERMIT_ALL);
            // Start with the class level @RolesAllowed
            HashSet<String> localRoles = new HashSet<>(allRoles);
            if (denyAll != null) {
                // To deny access we need a security constraint with an empty roles which we indicate by a null
                localRoles = null;
            } else if (permitAll != null) {
                // To permit all access we need a security contraint with no auth contraint which we indicate by an empty roles
                localRoles.clear();
            } else if (rolesAllowed != null) {
                // Override the class level roles
                localRoles.clear();
                localRoles.addAll(Arrays.asList(rolesAllowed.value().asStringArray()));
            } else if (classIsDenyAll) {
                localRoles = null;
            } else if (classIsPermitAll) {
                localRoles.clear();
            }
            String uriPath;
            if (subpath.charAt(0) == '/') {
                uriPath = fullAppPath.toString() + subpath.substring(1);
            } else {
                uriPath = fullAppPath.toString() + subpath;
            }
            // If this uri includes a path param, truncate and add a wildcard
            int pathParamStart = uriPath.indexOf('{');
            if (pathParamStart >= 0) {
                uriPath = uriPath.substring(0, pathParamStart);
                if (uriPath.charAt(uriPath.length() - 1) != '/') {
                    uriPath += '/';
                }
                uriPath += "*";
            }
            SecurityConstraint sc = webXml.protect(uriPath);
            // No roles == @DenyAll
            if (localRoles == null) {
                sc.withRole("");
            // Empy roles == @PermitAll
            } else if (localRoles.isEmpty()) {
                sc.permitAll();
            } else {
                localRoles.forEach(sc::withRole);
            }
            newConstraints.add(sc);
        }
    }
    if (log.isDebugEnabled()) {
        log.debugf("SecurityConstraints introduced by class: %s", classInfo.name());
        for (SecurityConstraint sc : newConstraints) {
            log.debugf("SecurityConstraint(%s), roles=%s, isPermitAll=%s", sc.urlPattern(), sc.roles(), sc.isPermitAll());
        }
    }
    scannedClasses.add(classInfo.name());
}
Also used : ArrayList(java.util.ArrayList) SecurityConstraint(org.wildfly.swarm.undertow.descriptors.SecurityConstraint) SecurityConstraint(org.wildfly.swarm.undertow.descriptors.SecurityConstraint) MethodInfo(org.jboss.jandex.MethodInfo) AnnotationInstance(org.jboss.jandex.AnnotationInstance) HashSet(java.util.HashSet)

Example 2 with SecurityConstraint

use of org.wildfly.swarm.undertow.descriptors.SecurityConstraint in project wildfly-swarm by wildfly-swarm.

the class WebXmlAssetTest method testSecurityConstraintPermitAll.

@Test
public void testSecurityConstraintPermitAll() throws IOException {
    WebXmlAsset asset = new WebXmlAsset();
    asset.protect().permitAll();
    List<SecurityConstraint> constraints = asset.allConstraints();
    assertThat(constraints).hasSize(1);
    SecurityConstraint sc = constraints.get(0);
    assertThat(sc.isPermitAll()).isEqualTo(true);
    InputStreamReader reader = new InputStreamReader(asset.openStream());
    BufferedReader buffered = new BufferedReader(reader);
    StringBuilder tmp = new StringBuilder();
    String line = buffered.readLine();
    while (line != null) {
        tmp.append(line);
        line = buffered.readLine();
    }
    assertThat(tmp.toString()).contains("security-constraint");
    assertThat(tmp.toString()).doesNotContain("auth-constraint");
}
Also used : InputStreamReader(java.io.InputStreamReader) WebXmlAsset(org.wildfly.swarm.undertow.descriptors.WebXmlAsset) BufferedReader(java.io.BufferedReader) SecurityConstraint(org.wildfly.swarm.undertow.descriptors.SecurityConstraint) Test(org.junit.Test)

Example 3 with SecurityConstraint

use of org.wildfly.swarm.undertow.descriptors.SecurityConstraint in project wildfly-swarm by wildfly-swarm.

the class HttpSecurityPreparer method process.

@SuppressWarnings("unchecked")
@Override
public void process() {
    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()) {
        // no matching archive
        return;
    }
    Map<String, Object> matchingConfig = (Map<String, Object>) deploymentConfigs.get(match.get());
    if (!matchingConfig.containsKey("web")) {
        // missing web configuration
        return;
    }
    Map<String, Object> deploymentConfig = (Map<String, Object>) matchingConfig.get("web");
    WARArchive war = archive.as(WARArchive.class);
    WebXmlAsset webXml = war.findWebXmlAsset();
    JBossWebAsset jbossWeb = war.findJbossWebAsset();
    // login-config
    Map<String, Object> loginConfig = (Map<String, Object>) deploymentConfig.get("login-config");
    if (loginConfig != null) {
        String authMethod = (String) loginConfig.getOrDefault("auth-method", "NONE");
        // 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);
    }
}
Also used : DeploymentProcessor(org.wildfly.swarm.spi.api.DeploymentProcessor) DeploymentScoped(org.wildfly.swarm.spi.runtime.annotations.DeploymentScoped) Logger(org.jboss.logging.Logger) JBossWebAsset(org.wildfly.swarm.undertow.descriptors.JBossWebAsset) Archive(org.jboss.shrinkwrap.api.Archive) WebXmlAsset(org.wildfly.swarm.undertow.descriptors.WebXmlAsset) SecurityConstraint(org.wildfly.swarm.undertow.descriptors.SecurityConstraint) Inject(javax.inject.Inject) List(java.util.List) Configurable(org.wildfly.swarm.spi.api.annotations.Configurable) Map(java.util.Map) WARArchive(org.wildfly.swarm.undertow.WARArchive) AttributeDocumentation(org.wildfly.swarm.config.runtime.AttributeDocumentation) Optional(java.util.Optional) Collections(java.util.Collections) JBossWebAsset(org.wildfly.swarm.undertow.descriptors.JBossWebAsset) WebXmlAsset(org.wildfly.swarm.undertow.descriptors.WebXmlAsset) WARArchive(org.wildfly.swarm.undertow.WARArchive) SecurityConstraint(org.wildfly.swarm.undertow.descriptors.SecurityConstraint) List(java.util.List) Map(java.util.Map)

Aggregations

SecurityConstraint (org.wildfly.swarm.undertow.descriptors.SecurityConstraint)3 WebXmlAsset (org.wildfly.swarm.undertow.descriptors.WebXmlAsset)2 BufferedReader (java.io.BufferedReader)1 InputStreamReader (java.io.InputStreamReader)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 Inject (javax.inject.Inject)1 AnnotationInstance (org.jboss.jandex.AnnotationInstance)1 MethodInfo (org.jboss.jandex.MethodInfo)1 Logger (org.jboss.logging.Logger)1 Archive (org.jboss.shrinkwrap.api.Archive)1 Test (org.junit.Test)1 AttributeDocumentation (org.wildfly.swarm.config.runtime.AttributeDocumentation)1 DeploymentProcessor (org.wildfly.swarm.spi.api.DeploymentProcessor)1 Configurable (org.wildfly.swarm.spi.api.annotations.Configurable)1 DeploymentScoped (org.wildfly.swarm.spi.runtime.annotations.DeploymentScoped)1