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());
}
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");
}
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);
}
}
Aggregations