keycloak-memoizeit
Changes
adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakBaseSpringBootConfiguration.java 14(+7 -7)
adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolver.java 22(+6 -16)
adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolverWrapper.java 48(+48 -0)
Details
diff --git a/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakBaseSpringBootConfiguration.java b/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakBaseSpringBootConfiguration.java
index 143368a..47bc708 100755
--- a/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakBaseSpringBootConfiguration.java
+++ b/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakBaseSpringBootConfiguration.java
@@ -32,10 +32,10 @@ import org.eclipse.jetty.server.handler.HandlerList;
 import org.eclipse.jetty.server.handler.HandlerWrapper;
 import org.eclipse.jetty.util.security.Constraint;
 import org.eclipse.jetty.webapp.WebAppContext;
-import org.keycloak.adapters.KeycloakConfigResolver;
 import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
 import org.keycloak.adapters.undertow.KeycloakServletExtension;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -55,9 +55,9 @@ public class KeycloakBaseSpringBootConfiguration {
         KeycloakSpringBootConfigResolver.setAdapterConfig(keycloakProperties);
     }
 
-    @Autowired (required = false)
-    public void setKeycloakConfigResolvers(KeycloakConfigResolver configResolver) {
-        KeycloakSpringBootConfigResolver.setDelegateConfigResolver(configResolver);
+    @Autowired
+    public void setApplicationContext(ApplicationContext context) {
+        KeycloakSpringBootConfigResolverWrapper.setApplicationContext(context);
     }
 
     static class KeycloakBaseUndertowDeploymentInfoCustomizer  {
@@ -75,7 +75,7 @@ public class KeycloakBaseSpringBootConfiguration {
 
             deploymentInfo.setLoginConfig(loginConfig);
 
-            deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
+            deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolverWrapper.class.getName());
             deploymentInfo.addSecurityConstraints(getSecurityConstraints());
 
             deploymentInfo.addServletExtension(new KeycloakServletExtension());
@@ -117,7 +117,7 @@ public class KeycloakBaseSpringBootConfiguration {
         public void customize(Server server) {
 
             KeycloakJettyAuthenticator keycloakJettyAuthenticator = new KeycloakJettyAuthenticator();
-            keycloakJettyAuthenticator.setConfigResolver(new KeycloakSpringBootConfigResolver());
+            keycloakJettyAuthenticator.setConfigResolver(new KeycloakSpringBootConfigResolverWrapper());
 
             /* see org.eclipse.jetty.webapp.StandardDescriptorProcessor#visitSecurityConstraint for an example
                on how to map servlet spec to Constraints */
@@ -268,7 +268,7 @@ public class KeycloakBaseSpringBootConfiguration {
                 context.addConstraint(tomcatConstraint);
             }
 
-            context.addParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
+            context.addParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolverWrapper.class.getName());
         }
     }
 }
                diff --git a/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolver.java b/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolver.java
index 8e809c5..2f90402 100755
--- a/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolver.java
+++ b/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolver.java
@@ -17,7 +17,6 @@
 
 package org.keycloak.adapters.springboot;
 
-import org.keycloak.adapters.KeycloakConfigResolver;
 import org.keycloak.adapters.KeycloakDeployment;
 import org.keycloak.adapters.KeycloakDeploymentBuilder;
 import org.keycloak.adapters.OIDCHttpFacade;
@@ -25,31 +24,22 @@ import org.keycloak.representations.adapters.config.AdapterConfig;
 
 public class KeycloakSpringBootConfigResolver implements org.keycloak.adapters.KeycloakConfigResolver {
 
-    private static AdapterConfig adapterConfig;
-    private static KeycloakConfigResolver delegateConfigResolver;
-
     private KeycloakDeployment keycloakDeployment;
 
+    private static AdapterConfig adapterConfig;
+
     @Override
     public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
-        if (delegateConfigResolver == null) {
-            if (keycloakDeployment != null) {
-                return keycloakDeployment;
-            }
-
-            keycloakDeployment = KeycloakDeploymentBuilder.build(KeycloakSpringBootConfigResolver.adapterConfig);
-
+        if (keycloakDeployment != null) {
             return keycloakDeployment;
         }
 
-        return delegateConfigResolver.resolve(request);
+        keycloakDeployment = KeycloakDeploymentBuilder.build(KeycloakSpringBootConfigResolver.adapterConfig);
+
+        return keycloakDeployment;
     }
 
     static void setAdapterConfig(AdapterConfig adapterConfig) {
         KeycloakSpringBootConfigResolver.adapterConfig = adapterConfig;
     }
-
-    static void setDelegateConfigResolver(KeycloakConfigResolver configResolver) {
-        KeycloakSpringBootConfigResolver.delegateConfigResolver = configResolver;
-    }
 }
\ No newline at end of file
                diff --git a/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolverWrapper.java b/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolverWrapper.java
new file mode 100644
index 0000000..34ae3ad
--- /dev/null
+++ b/adapters/oidc/spring-boot-adapter-core/src/main/java/org/keycloak/adapters/springboot/KeycloakSpringBootConfigResolverWrapper.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.keycloak.adapters.springboot;
+
+import org.keycloak.adapters.KeycloakConfigResolver;
+import org.keycloak.adapters.springsecurity.config.KeycloakSpringConfigResolverWrapper;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * <p>A specific implementation of {@link KeycloakSpringConfigResolverWrapper} that first tries to register any {@link KeycloakConfigResolver}
+ * instance provided by the application. if none is provided, {@link KeycloakSpringBootConfigResolver} is set.
+ *
+ * <p>This implementation is specially useful when using Spring Boot and Spring Security in the same application where the same {@link KeycloakConfigResolver}
+ * instance must be used across the different stacks.
+ *
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public class KeycloakSpringBootConfigResolverWrapper extends KeycloakSpringConfigResolverWrapper {
+
+    private static ApplicationContext context;
+
+    public KeycloakSpringBootConfigResolverWrapper() {
+        super(new KeycloakSpringBootConfigResolver());
+        try {
+            setDelegate(context.getBean(KeycloakConfigResolver.class));
+        } catch (NoSuchBeanDefinitionException ignore) {
+        }
+    }
+
+    public static void setApplicationContext(ApplicationContext context) {
+        KeycloakSpringBootConfigResolverWrapper.context = context;
+    }
+}
                diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakSpringConfigResolverWrapper.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakSpringConfigResolverWrapper.java
new file mode 100644
index 0000000..d467f32
--- /dev/null
+++ b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakSpringConfigResolverWrapper.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.keycloak.adapters.springsecurity.config;
+
+import org.keycloak.adapters.KeycloakConfigResolver;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.spi.HttpFacade;
+
+/**
+ * Spring applications may use different security stacks in order to enforce access based on the configuration provided
+ * by a {@code KeycloakDeployment}. This implementation of {@code KeycloakConfigResolver} wraps and avoid calling multiple
+ * {@code KeycloakConfigResolver} instances but only those defined by applications or set as default by the configuration.
+ *
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public class KeycloakSpringConfigResolverWrapper implements KeycloakConfigResolver {
+
+    private KeycloakConfigResolver delegate;
+
+    public KeycloakSpringConfigResolverWrapper(KeycloakConfigResolver delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public KeycloakDeployment resolve(HttpFacade.Request facade) {
+        return delegate.resolve(facade);
+    }
+
+    protected void setDelegate(KeycloakConfigResolver delegate) {
+        this.delegate = delegate;
+    }
+}
                diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java
index 2f27b58..9d34497 100644
--- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java
+++ b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java
@@ -65,7 +65,7 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
     protected AdapterDeploymentContext adapterDeploymentContext() throws Exception {
         AdapterDeploymentContextFactoryBean factoryBean;
         if (keycloakConfigResolver != null) {
-             factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigResolver);
+             factoryBean = new AdapterDeploymentContextFactoryBean(new KeycloakSpringConfigResolverWrapper(keycloakConfigResolver));
         }
         else {
             factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigFileResource);