From f574173ed3479839018de4b215c356f2accc0e41 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Mon, 18 Jul 2016 10:00:24 +0200 Subject: [PATCH] KEYCLOAK-3301 Add support for Undertow in Spring Boot Adapter We now support using Undertow in combination with the Spring Boot Adapter. --- adapters/oidc/spring-boot/pom.xml | 18 +++++++ .../KeycloakSpringBootConfiguration.java | 51 ++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/adapters/oidc/spring-boot/pom.xml b/adapters/oidc/spring-boot/pom.xml index a60441d26e..1d24a547ac 100755 --- a/adapters/oidc/spring-boot/pom.xml +++ b/adapters/oidc/spring-boot/pom.xml @@ -88,6 +88,24 @@ provided + + io.undertow + undertow-servlet + provided + + + + io.undertow + undertow-core + provided + + + + org.keycloak + keycloak-undertow-adapter-spi + provided + + junit junit 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 68c750c973..5c1b54678c 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 @@ -17,6 +17,8 @@ package org.keycloak.adapters.springboot; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.WebResourceCollection; import org.apache.catalina.Context; import org.apache.tomcat.util.descriptor.web.LoginConfig; import org.apache.tomcat.util.descriptor.web.SecurityCollection; @@ -28,6 +30,7 @@ import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.webapp.WebAppContext; import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator; import org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve; +import org.keycloak.adapters.undertow.KeycloakServletExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; @@ -108,7 +111,53 @@ public class KeycloakSpringBootConfiguration { @Bean @ConditionalOnClass(name = {"io.undertow.Undertow"}) public UndertowDeploymentInfoCustomizer undertowKeycloakContextCustomizer() { - throw new IllegalArgumentException("Undertow Keycloak integration is not yet implemented"); + return new KeycloakUndertowDeploymentInfoCustomizer(keycloakProperties); + } + + static class KeycloakUndertowDeploymentInfoCustomizer implements UndertowDeploymentInfoCustomizer { + + private final KeycloakSpringBootProperties keycloakProperties; + + public KeycloakUndertowDeploymentInfoCustomizer(KeycloakSpringBootProperties keycloakProperties) { + this.keycloakProperties = keycloakProperties; + } + + @Override + public void customize(DeploymentInfo deploymentInfo) { + + io.undertow.servlet.api.LoginConfig loginConfig = new io.undertow.servlet.api.LoginConfig(keycloakProperties.getRealm()); + loginConfig.addFirstAuthMethod("KEYCLOAK"); + + deploymentInfo.setLoginConfig(loginConfig); + + deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName()); + deploymentInfo.addSecurityConstraints(getSecurityConstraints()); + + deploymentInfo.addServletExtension(new KeycloakServletExtension()); + } + + private List getSecurityConstraints() { + + List undertowSecurityConstraints = new ArrayList(); + 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(collectionDefinition.getAuthRoles()); + + WebResourceCollection webResourceCollection = new WebResourceCollection(); + webResourceCollection.addHttpMethods(collectionDefinition.getMethods()); + webResourceCollection.addHttpMethodOmissions(collectionDefinition.getOmittedMethods()); + webResourceCollection.addUrlPatterns(collectionDefinition.getPatterns()); + + undertowSecurityConstraint.addWebResourceCollections(webResourceCollection); + + undertowSecurityConstraints.add(undertowSecurityConstraint); + } + } + return undertowSecurityConstraints; + } } static class KeycloakJettyServerCustomizer implements JettyServerCustomizer {