[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.server.handler.HandlerWrapper;
|
||||||
import org.eclipse.jetty.util.security.Constraint;
|
import org.eclipse.jetty.util.security.Constraint;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.keycloak.adapters.KeycloakConfigResolver;
|
|
||||||
import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
|
import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
|
||||||
import org.keycloak.adapters.undertow.KeycloakServletExtension;
|
import org.keycloak.adapters.undertow.KeycloakServletExtension;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -55,9 +55,9 @@ public class KeycloakBaseSpringBootConfiguration {
|
||||||
KeycloakSpringBootConfigResolver.setAdapterConfig(keycloakProperties);
|
KeycloakSpringBootConfigResolver.setAdapterConfig(keycloakProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired (required = false)
|
@Autowired
|
||||||
public void setKeycloakConfigResolvers(KeycloakConfigResolver configResolver) {
|
public void setApplicationContext(ApplicationContext context) {
|
||||||
KeycloakSpringBootConfigResolver.setDelegateConfigResolver(configResolver);
|
KeycloakSpringBootConfigResolverWrapper.setApplicationContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class KeycloakBaseUndertowDeploymentInfoCustomizer {
|
static class KeycloakBaseUndertowDeploymentInfoCustomizer {
|
||||||
|
@ -75,7 +75,7 @@ public class KeycloakBaseSpringBootConfiguration {
|
||||||
|
|
||||||
deploymentInfo.setLoginConfig(loginConfig);
|
deploymentInfo.setLoginConfig(loginConfig);
|
||||||
|
|
||||||
deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolver.class.getName());
|
deploymentInfo.addInitParameter("keycloak.config.resolver", KeycloakSpringBootConfigResolverWrapper.class.getName());
|
||||||
deploymentInfo.addSecurityConstraints(getSecurityConstraints());
|
deploymentInfo.addSecurityConstraints(getSecurityConstraints());
|
||||||
|
|
||||||
deploymentInfo.addServletExtension(new KeycloakServletExtension());
|
deploymentInfo.addServletExtension(new KeycloakServletExtension());
|
||||||
|
@ -117,7 +117,7 @@ public class KeycloakBaseSpringBootConfiguration {
|
||||||
public void customize(Server server) {
|
public void customize(Server server) {
|
||||||
|
|
||||||
KeycloakJettyAuthenticator keycloakJettyAuthenticator = new KeycloakJettyAuthenticator();
|
KeycloakJettyAuthenticator keycloakJettyAuthenticator = new KeycloakJettyAuthenticator();
|
||||||
keycloakJettyAuthenticator.setConfigResolver(new KeycloakSpringBootConfigResolver());
|
keycloakJettyAuthenticator.setConfigResolver(new KeycloakSpringBootConfigResolverWrapper());
|
||||||
|
|
||||||
/* see org.eclipse.jetty.webapp.StandardDescriptorProcessor#visitSecurityConstraint for an example
|
/* see org.eclipse.jetty.webapp.StandardDescriptorProcessor#visitSecurityConstraint for an example
|
||||||
on how to map servlet spec to Constraints */
|
on how to map servlet spec to Constraints */
|
||||||
|
@ -268,7 +268,7 @@ public class KeycloakBaseSpringBootConfiguration {
|
||||||
context.addConstraint(tomcatConstraint);
|
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;
|
package org.keycloak.adapters.springboot;
|
||||||
|
|
||||||
import org.keycloak.adapters.KeycloakConfigResolver;
|
|
||||||
import org.keycloak.adapters.KeycloakDeployment;
|
import org.keycloak.adapters.KeycloakDeployment;
|
||||||
import org.keycloak.adapters.KeycloakDeploymentBuilder;
|
import org.keycloak.adapters.KeycloakDeploymentBuilder;
|
||||||
import org.keycloak.adapters.OIDCHttpFacade;
|
import org.keycloak.adapters.OIDCHttpFacade;
|
||||||
|
@ -25,14 +24,12 @@ import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||||
|
|
||||||
public class KeycloakSpringBootConfigResolver implements org.keycloak.adapters.KeycloakConfigResolver {
|
public class KeycloakSpringBootConfigResolver implements org.keycloak.adapters.KeycloakConfigResolver {
|
||||||
|
|
||||||
private static AdapterConfig adapterConfig;
|
|
||||||
private static KeycloakConfigResolver delegateConfigResolver;
|
|
||||||
|
|
||||||
private KeycloakDeployment keycloakDeployment;
|
private KeycloakDeployment keycloakDeployment;
|
||||||
|
|
||||||
|
private static AdapterConfig adapterConfig;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
|
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
|
||||||
if (delegateConfigResolver == null) {
|
|
||||||
if (keycloakDeployment != null) {
|
if (keycloakDeployment != null) {
|
||||||
return keycloakDeployment;
|
return keycloakDeployment;
|
||||||
}
|
}
|
||||||
|
@ -42,14 +39,7 @@ public class KeycloakSpringBootConfigResolver implements org.keycloak.adapters.K
|
||||||
return keycloakDeployment;
|
return keycloakDeployment;
|
||||||
}
|
}
|
||||||
|
|
||||||
return delegateConfigResolver.resolve(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setAdapterConfig(AdapterConfig adapterConfig) {
|
static void setAdapterConfig(AdapterConfig adapterConfig) {
|
||||||
KeycloakSpringBootConfigResolver.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 {
|
protected AdapterDeploymentContext adapterDeploymentContext() throws Exception {
|
||||||
AdapterDeploymentContextFactoryBean factoryBean;
|
AdapterDeploymentContextFactoryBean factoryBean;
|
||||||
if (keycloakConfigResolver != null) {
|
if (keycloakConfigResolver != null) {
|
||||||
factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigResolver);
|
factoryBean = new AdapterDeploymentContextFactoryBean(new KeycloakSpringConfigResolverWrapper(keycloakConfigResolver));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigFileResource);
|
factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigFileResource);
|
||||||
|
|
Loading…
Reference in a new issue