[KEYCLOAK-8444] - Error when producing KeycloakSpringBootConfigResolver from spring security configuration
This commit is contained in:
parent
531ee3a1be
commit
6fd4a02f95
5 changed files with 108 additions and 24 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue