keycloak-uncached
Merge pull request #3838 from ahus1/KEYCLOAK-4208-spring-boot-adapter-roles KEYCLOAK-4208 …
4/21/2017 10:34:09 AM
Changes
adapters/oidc/spring-boot/pom.xml 2(+1 -1)
Details
adapters/oidc/spring-boot/pom.xml 2(+1 -1)
diff --git a/adapters/oidc/spring-boot/pom.xml b/adapters/oidc/spring-boot/pom.xml
index 0abc3d8..48a2809 100755
--- a/adapters/oidc/spring-boot/pom.xml
+++ b/adapters/oidc/spring-boot/pom.xml
@@ -56,7 +56,7 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-jetty92-adapter</artifactId>
+ <artifactId>keycloak-jetty93-adapter</artifactId>
<scope>provided</scope>
</dependency>
diff --git a/adapters/oidc/spring-boot/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfiguration.java b/adapters/oidc/spring-boot/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfiguration.java
index d4c9858..657f8e3 100755
--- a/adapters/oidc/spring-boot/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfiguration.java
+++ b/adapters/oidc/spring-boot/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfiguration.java
@@ -141,10 +141,10 @@ public class KeycloakSpringBootConfiguration {
List<io.undertow.servlet.api.SecurityConstraint> undertowSecurityConstraints = new ArrayList<io.undertow.servlet.api.SecurityConstraint>();
for (KeycloakSpringBootProperties.SecurityConstraint constraintDefinition : keycloakProperties.getSecurityConstraints()) {
- for (KeycloakSpringBootProperties.SecurityCollection collectionDefinition : constraintDefinition.getSecurityCollections()) {
+ io.undertow.servlet.api.SecurityConstraint undertowSecurityConstraint = new io.undertow.servlet.api.SecurityConstraint();
+ undertowSecurityConstraint.addRolesAllowed(constraintDefinition.getAuthRoles());
- io.undertow.servlet.api.SecurityConstraint undertowSecurityConstraint = new io.undertow.servlet.api.SecurityConstraint();
- undertowSecurityConstraint.addRolesAllowed(collectionDefinition.getAuthRoles());
+ for (KeycloakSpringBootProperties.SecurityCollection collectionDefinition : constraintDefinition.getSecurityCollections()) {
WebResourceCollection webResourceCollection = new WebResourceCollection();
webResourceCollection.addHttpMethods(collectionDefinition.getMethods());
@@ -153,8 +153,9 @@ public class KeycloakSpringBootConfiguration {
undertowSecurityConstraint.addWebResourceCollections(webResourceCollection);
- undertowSecurityConstraints.add(undertowSecurityConstraint);
}
+
+ undertowSecurityConstraints.add(undertowSecurityConstraint);
}
return undertowSecurityConstraints;
}
@@ -174,38 +175,62 @@ public class KeycloakSpringBootConfiguration {
KeycloakJettyAuthenticator keycloakJettyAuthenticator = new KeycloakJettyAuthenticator();
keycloakJettyAuthenticator.setConfigResolver(new KeycloakSpringBootConfigResolver());
+ /* see org.eclipse.jetty.webapp.StandardDescriptorProcessor#visitSecurityConstraint for an example
+ on how to map servlet spec to Constraints */
+
List<ConstraintMapping> jettyConstraintMappings = new ArrayList<ConstraintMapping>();
for (KeycloakSpringBootProperties.SecurityConstraint constraintDefinition : keycloakProperties.getSecurityConstraints()) {
for (KeycloakSpringBootProperties.SecurityCollection securityCollectionDefinition : constraintDefinition
.getSecurityCollections()) {
-
+ // securityCollection matches servlet spec's web-resource-collection
Constraint jettyConstraint = new Constraint();
- jettyConstraint.setName(securityCollectionDefinition.getName());
- jettyConstraint.setAuthenticate(true);
- if (securityCollectionDefinition.getName() != null) {
- jettyConstraint.setName(securityCollectionDefinition.getName());
+ if (constraintDefinition.getAuthRoles().size() > 0) {
+ jettyConstraint.setAuthenticate(true);
+ jettyConstraint.setRoles(constraintDefinition.getAuthRoles().toArray(new String[0]));
}
- jettyConstraint.setRoles(securityCollectionDefinition.getAuthRoles().toArray(new String[0]));
+ jettyConstraint.setName(securityCollectionDefinition.getName());
- ConstraintMapping jettyConstraintMapping = new ConstraintMapping();
- if (securityCollectionDefinition.getPatterns().size() > 0) {
- //First pattern wins
- jettyConstraintMapping.setPathSpec(securityCollectionDefinition.getPatterns().get(0));
- jettyConstraintMapping.setConstraint(jettyConstraint);
- }
+ // according to the servlet spec each security-constraint has at least one URL pattern
+ for(String pattern : securityCollectionDefinition.getPatterns()) {
+
+ /* the following code is asymmetric as Jetty's ConstraintMapping accepts only one allowed HTTP method,
+ but multiple omitted methods. Therefore we add one ConstraintMapping for each allowed
+ mapping but only one mapping in the cases of omitted methods or no methods.
+ */
+
+ if (securityCollectionDefinition.getMethods().size() > 0) {
+ // according to the servlet spec we have either methods ...
+ for(String method : securityCollectionDefinition.getMethods()) {
+ ConstraintMapping jettyConstraintMapping = new ConstraintMapping();
+ jettyConstraintMappings.add(jettyConstraintMapping);
+
+ jettyConstraintMapping.setConstraint(jettyConstraint);
+ jettyConstraintMapping.setPathSpec(pattern);
+ jettyConstraintMapping.setMethod(method);
+ }
+ } else if (securityCollectionDefinition.getOmittedMethods().size() > 0){
+ // ... omitted methods ...
+ ConstraintMapping jettyConstraintMapping = new ConstraintMapping();
+ jettyConstraintMappings.add(jettyConstraintMapping);
+
+ jettyConstraintMapping.setConstraint(jettyConstraint);
+ jettyConstraintMapping.setPathSpec(pattern);
+ jettyConstraintMapping.setMethodOmissions(
+ securityCollectionDefinition.getOmittedMethods().toArray(new String[0]));
+ } else {
+ // ... or no methods at all
+ ConstraintMapping jettyConstraintMapping = new ConstraintMapping();
+ jettyConstraintMappings.add(jettyConstraintMapping);
+
+ jettyConstraintMapping.setConstraint(jettyConstraint);
+ jettyConstraintMapping.setPathSpec(pattern);
+ }
- if (securityCollectionDefinition.getMethods().size() > 0) {
- //First method wins
- jettyConstraintMapping.setMethod(securityCollectionDefinition.getMethods().get(0));
}
- jettyConstraintMapping.setMethodOmissions(
- securityCollectionDefinition.getOmittedMethods().toArray(new String[0]));
-
- jettyConstraintMappings.add(jettyConstraintMapping);
}
}
@@ -239,12 +264,10 @@ public class KeycloakSpringBootConfiguration {
Set<String> authRoles = new HashSet<String>();
for (KeycloakSpringBootProperties.SecurityConstraint constraint : keycloakProperties.getSecurityConstraints()) {
- for (KeycloakSpringBootProperties.SecurityCollection collection : constraint.getSecurityCollections()) {
- for (String authRole : collection.getAuthRoles()) {
- if (!authRoles.contains(authRole)) {
- context.addSecurityRole(authRole);
- authRoles.add(authRole);
- }
+ for (String authRole : constraint.getAuthRoles()) {
+ if (!authRoles.contains(authRole)) {
+ context.addSecurityRole(authRole);
+ authRoles.add(authRole);
}
}
}
@@ -252,6 +275,10 @@ public class KeycloakSpringBootConfiguration {
for (KeycloakSpringBootProperties.SecurityConstraint constraint : keycloakProperties.getSecurityConstraints()) {
SecurityConstraint tomcatConstraint = new SecurityConstraint();
+ for (String authRole : constraint.getAuthRoles()) {
+ tomcatConstraint.addAuthRole(authRole);
+ }
+
for (KeycloakSpringBootProperties.SecurityCollection collection : constraint.getSecurityCollections()) {
SecurityCollection tomcatSecCollection = new SecurityCollection();
@@ -262,10 +289,6 @@ public class KeycloakSpringBootConfiguration {
tomcatSecCollection.setDescription(collection.getDescription());
}
- for (String authRole : collection.getAuthRoles()) {
- tomcatConstraint.addAuthRole(authRole);
- }
-
for (String pattern : collection.getPatterns()) {
tomcatSecCollection.addPattern(pattern);
}
diff --git a/adapters/oidc/spring-boot/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootProperties.java b/adapters/oidc/spring-boot/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootProperties.java
index 2c99eba..788412f 100644
--- a/adapters/oidc/spring-boot/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootProperties.java
+++ b/adapters/oidc/spring-boot/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootProperties.java
@@ -43,12 +43,20 @@ public class KeycloakSpringBootProperties extends AdapterConfig {
*/
private List<SecurityConstraint> securityConstraints = new ArrayList<SecurityConstraint>();
+ /**
+ * This matches security-constraint of the servlet spec
+ */
@ConfigurationProperties()
public static class SecurityConstraint {
/**
* A list of security collections
*/
private List<SecurityCollection> securityCollections = new ArrayList<SecurityCollection>();
+ private List<String> authRoles = new ArrayList<String>();
+
+ public List<String> getAuthRoles() {
+ return authRoles;
+ }
public List<SecurityCollection> getSecurityCollections() {
return securityCollections;
@@ -57,7 +65,16 @@ public class KeycloakSpringBootProperties extends AdapterConfig {
public void setSecurityCollections(List<SecurityCollection> securityCollections) {
this.securityCollections = securityCollections;
}
+
+ public void setAuthRoles(List<String> authRoles) {
+ this.authRoles = authRoles;
+ }
+
}
+
+ /**
+ * This matches web-resource-collection of the servlet spec
+ */
@ConfigurationProperties()
public static class SecurityCollection {
/**
@@ -69,10 +86,6 @@ public class KeycloakSpringBootProperties extends AdapterConfig {
*/
private String description;
/**
- * A list of roles that applies for this security collection
- */
- private List<String> authRoles = new ArrayList<String>();
- /**
* A list of URL patterns that should match to apply the security collection
*/
private List<String> patterns = new ArrayList<String>();
@@ -85,10 +98,6 @@ public class KeycloakSpringBootProperties extends AdapterConfig {
*/
private List<String> omittedMethods = new ArrayList<String>();
- public List<String> getAuthRoles() {
- return authRoles;
- }
-
public List<String> getPatterns() {
return patterns;
}
@@ -117,10 +126,6 @@ public class KeycloakSpringBootProperties extends AdapterConfig {
this.description = description;
}
- public void setAuthRoles(List<String> authRoles) {
- this.authRoles = authRoles;
- }
-
public void setPatterns(List<String> patterns) {
this.patterns = patterns;
}