From 566a58b5d82fd25b872a2381d07c383ae7e2738d Mon Sep 17 00:00:00 2001 From: Thomas Raehalme Date: Tue, 15 Dec 2015 11:53:10 +0200 Subject: [PATCH 1/9] Replaced AdapterDeploymentContextBean with AdapterDeploymentContextFactoryBean and added support for KeycloakConfigResolver. --- .../AdapterDeploymentContextBean.java | 64 --------------- .../AdapterDeploymentContextFactoryBean.java | 79 +++++++++++++++++++ .../authentication/KeycloakLogoutHandler.java | 15 ++-- .../KeycloakWebSecurityConfigurerAdapter.java | 23 ++++-- ...eycloakAuthenticationProcessingFilter.java | 11 +-- .../filter/KeycloakPreAuthActionsFilter.java | 5 +- .../AdapterDeploymentContextBeanTest.java | 56 ------------- ...apterDeploymentContextFactoryBeanTest.java | 77 ++++++++++++++++++ .../KeycloakLogoutHandlerTest.java | 9 ++- ...oakAuthenticationProcessingFilterTest.java | 9 ++- 10 files changed, 200 insertions(+), 148 deletions(-) delete mode 100644 integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextBean.java create mode 100644 integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBean.java delete mode 100644 integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextBeanTest.java create mode 100644 integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBeanTest.java diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextBean.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextBean.java deleted file mode 100644 index a517416396..0000000000 --- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextBean.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.keycloak.adapters.springsecurity; - -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.KeycloakDeploymentBuilder; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.io.Resource; - -import java.io.FileNotFoundException; -import java.io.IOException; - -/** - * Bean holding the {@link KeycloakDeployment} and {@link AdapterDeploymentContext} for this - * Spring application context. The Keycloak deployment is loaded from the required - * keycloak.json resource file. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class AdapterDeploymentContextBean implements InitializingBean { - - private final Resource keycloakConfigFileResource; - - private AdapterDeploymentContext deploymentContext; - private KeycloakDeployment deployment; - - public AdapterDeploymentContextBean(Resource keycloakConfigFileResource) { - this.keycloakConfigFileResource = keycloakConfigFileResource; - } - - @Override - public void afterPropertiesSet() throws Exception { - this.deployment = loadKeycloakDeployment(); - this.deploymentContext = new AdapterDeploymentContext(deployment); - } - - private KeycloakDeployment loadKeycloakDeployment() throws IOException { - - if (!keycloakConfigFileResource.isReadable()) { - throw new FileNotFoundException(String.format("Unable to locate Keycloak configuration file: %s", - keycloakConfigFileResource.getFilename())); - } - - return KeycloakDeploymentBuilder.build(keycloakConfigFileResource.getInputStream()); - } - - /** - * Returns the Keycloak {@link AdapterDeploymentContext} for this application context. - * - * @return the Keycloak {@link AdapterDeploymentContext} for this application context - */ - public AdapterDeploymentContext getDeploymentContext() { - return deploymentContext; - } - - /** - * Returns the {@link KeycloakDeployment} for this application context. - * - * @return the {@link KeycloakDeployment} for this application context - */ - public KeycloakDeployment getDeployment() { - return deployment; - } -} diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBean.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBean.java new file mode 100644 index 0000000000..d089ded86a --- /dev/null +++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBean.java @@ -0,0 +1,79 @@ +package org.keycloak.adapters.springsecurity; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Objects; + +import org.keycloak.adapters.AdapterDeploymentContext; +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.KeycloakDeploymentBuilder; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.io.Resource; + +/** + * {@link FactoryBean} that creates an {@link AdapterDeploymentContext} given a {@link Resource} defining the Keycloak + * client configuration or a {@link KeycloakConfigResolver} for multi-tenant environments. + * + * @author Thomas Raehalme + */ +public class AdapterDeploymentContextFactoryBean + implements FactoryBean, InitializingBean { + private static final Logger log = + LoggerFactory.getLogger(AdapterDeploymentContextFactoryBean.class); + private final Resource keycloakConfigFileResource; + private final KeycloakConfigResolver keycloakConfigResolver; + private AdapterDeploymentContext adapterDeploymentContext; + + public AdapterDeploymentContextFactoryBean(Resource keycloakConfigFileResource) { + this.keycloakConfigFileResource = Objects.requireNonNull(keycloakConfigFileResource); + this.keycloakConfigResolver = null; + } + + public AdapterDeploymentContextFactoryBean(KeycloakConfigResolver keycloakConfigResolver) { + this.keycloakConfigResolver = Objects.requireNonNull(keycloakConfigResolver); + this.keycloakConfigFileResource = null; + } + + @Override + public Class getObjectType() { + return AdapterDeploymentContext.class; + } + + @Override + public boolean isSingleton() { + return true; + } + + @Override + public void afterPropertiesSet() throws Exception { + if (keycloakConfigResolver != null) { + adapterDeploymentContext = new AdapterDeploymentContext(keycloakConfigResolver); + } + else { + log.info("Loading Keycloak deployment from configuration file: {}", keycloakConfigFileResource); + + KeycloakDeployment deployment = loadKeycloakDeployment(); + adapterDeploymentContext = new AdapterDeploymentContext(deployment); + } + } + + private KeycloakDeployment loadKeycloakDeployment() throws IOException { + if (!keycloakConfigFileResource.isReadable()) { + throw new FileNotFoundException(String.format("Unable to locate Keycloak configuration file: %s", + keycloakConfigFileResource.getFilename())); + } + + return KeycloakDeploymentBuilder.build(keycloakConfigFileResource.getInputStream()); + } + + @Override + public AdapterDeploymentContext getObject() throws Exception { + return adapterDeploymentContext; + } +} diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java index 27178ca2ad..c17dca1706 100644 --- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java +++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java @@ -1,8 +1,10 @@ package org.keycloak.adapters.springsecurity.authentication; +import org.keycloak.adapters.AdapterDeploymentContext; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean; +import org.keycloak.adapters.spi.HttpFacade; +import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,11 +25,11 @@ public class KeycloakLogoutHandler implements LogoutHandler { private static final Logger log = LoggerFactory.getLogger(KeycloakLogoutHandler.class); - private AdapterDeploymentContextBean deploymentContextBean; + private AdapterDeploymentContext adapterDeploymentContext; - public KeycloakLogoutHandler(AdapterDeploymentContextBean deploymentContextBean) { - Assert.notNull(deploymentContextBean); - this.deploymentContextBean = deploymentContextBean; + public KeycloakLogoutHandler(AdapterDeploymentContext adapterDeploymentContext) { + Assert.notNull(adapterDeploymentContext); + this.adapterDeploymentContext = adapterDeploymentContext; } @Override @@ -45,7 +47,8 @@ public class KeycloakLogoutHandler implements LogoutHandler { } protected void handleSingleSignOut(HttpServletRequest request, HttpServletResponse response, KeycloakAuthenticationToken authenticationToken) { - KeycloakDeployment deployment = deploymentContextBean.getDeployment(); + HttpFacade facade = new SimpleHttpFacade(request, response); + KeycloakDeployment deployment = adapterDeploymentContext.resolveDeployment(facade); RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) authenticationToken.getAccount().getKeycloakSecurityContext(); session.logout(deployment); } diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java index b5ef6659e3..55c6b3c700 100644 --- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java +++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java @@ -1,6 +1,8 @@ package org.keycloak.adapters.springsecurity.config; -import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean; +import org.keycloak.adapters.AdapterDeploymentContext; +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.springsecurity.AdapterDeploymentContextFactoryBean; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; import org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler; @@ -8,6 +10,7 @@ import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcess import org.keycloak.adapters.springsecurity.filter.KeycloakCsrfRequestMatcher; import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter; import org.keycloak.adapters.springsecurity.management.HttpSessionManager; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.core.io.Resource; @@ -35,10 +38,20 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo @Value("${keycloak.configurationFile:WEB-INF/keycloak.json}") private Resource keycloakConfigFileResource; + @Autowired(required = false) + private KeycloakConfigResolver keycloakConfigResolver; @Bean - protected AdapterDeploymentContextBean adapterDeploymentContextBean() { - return new AdapterDeploymentContextBean(keycloakConfigFileResource); + protected AdapterDeploymentContext adapterDeploymentContext() throws Exception { + AdapterDeploymentContextFactoryBean factoryBean; + if (keycloakConfigResolver != null) { + factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigResolver); + } + else { + factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigFileResource); + } + factoryBean.afterPropertiesSet(); + return factoryBean.getObject(); } protected AuthenticationEntryPoint authenticationEntryPoint() { @@ -70,8 +83,8 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo return new HttpSessionManager(); } - protected KeycloakLogoutHandler keycloakLogoutHandler() { - return new KeycloakLogoutHandler(adapterDeploymentContextBean()); + protected KeycloakLogoutHandler keycloakLogoutHandler() throws Exception { + return new KeycloakLogoutHandler(adapterDeploymentContext()); } protected abstract SessionAuthenticationStrategy sessionAuthenticationStrategy(); diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java index 965c1624ab..04c6ed3367 100644 --- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java +++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java @@ -1,11 +1,12 @@ package org.keycloak.adapters.springsecurity.filter; +import org.keycloak.adapters.AdapterDeploymentContext; import org.keycloak.adapters.AdapterTokenStore; import org.keycloak.adapters.spi.AuthChallenge; import org.keycloak.adapters.spi.AuthOutcome; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.RequestAuthenticator; -import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean; +import org.keycloak.adapters.spi.HttpFacade; import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint; import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticator; @@ -56,7 +57,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati private static final Logger log = LoggerFactory.getLogger(KeycloakAuthenticationProcessingFilter.class); private ApplicationContext applicationContext; - private AdapterDeploymentContextBean adapterDeploymentContextBean; + private AdapterDeploymentContext adapterDeploymentContext; private AdapterTokenStoreFactory adapterTokenStoreFactory = new SpringSecurityAdapterTokenStoreFactory(); private AuthenticationManager authenticationManager; @@ -100,7 +101,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati @Override public void afterPropertiesSet() { - adapterDeploymentContextBean = applicationContext.getBean(AdapterDeploymentContextBean.class); + adapterDeploymentContext = applicationContext.getBean(AdapterDeploymentContext.class); super.afterPropertiesSet(); } @@ -110,8 +111,8 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati log.debug("Attempting Keycloak authentication"); - KeycloakDeployment deployment = adapterDeploymentContextBean.getDeployment(); - SimpleHttpFacade facade = new SimpleHttpFacade(request, response); + HttpFacade facade = new SimpleHttpFacade(request, response); + KeycloakDeployment deployment = adapterDeploymentContext.resolveDeployment(facade); AdapterTokenStore tokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, request); RequestAuthenticator authenticator = new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, -1); diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java index 2363b3f1f3..565ae624ba 100755 --- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java +++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java @@ -5,7 +5,6 @@ import org.keycloak.adapters.spi.HttpFacade; import org.keycloak.adapters.NodesRegistrationManagement; import org.keycloak.adapters.PreAuthActionsHandler; import org.keycloak.adapters.spi.UserSessionManagement; -import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean; import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,9 +46,7 @@ public class KeycloakPreAuthActionsFilter extends GenericFilterBean implements A @Override protected void initFilterBean() throws ServletException { - AdapterDeploymentContextBean contextBean = applicationContext.getBean(AdapterDeploymentContextBean.class); - deploymentContext = contextBean.getDeploymentContext(); - management.tryRegister(contextBean.getDeployment()); + deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class); } @Override diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextBeanTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextBeanTest.java deleted file mode 100644 index 3510db7f7a..0000000000 --- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextBeanTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.keycloak.adapters.springsecurity; - - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import java.io.FileNotFoundException; - -import static org.junit.Assert.assertNotNull; - -public class AdapterDeploymentContextBeanTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private AdapterDeploymentContextBean adapterDeploymentContextBean; - - @Test - public void should_create_deployment_and_deployment_context() throws Exception { - - //given: - adapterDeploymentContextBean = new AdapterDeploymentContextBean(getCorrectResource()); - - //when: - adapterDeploymentContextBean.afterPropertiesSet(); - - //then - assertNotNull(adapterDeploymentContextBean.getDeployment()); - assertNotNull(adapterDeploymentContextBean.getDeploymentContext()); - } - - private Resource getCorrectResource() { - return new ClassPathResource("keycloak.json"); - } - - @Test - public void should_throw_exception_when_configuration_file_was_not_found() throws Exception { - - //given: - adapterDeploymentContextBean = new AdapterDeploymentContextBean(getEmptyResource()); - - //then: - expectedException.expect(FileNotFoundException.class); - expectedException.expectMessage("Unable to locate Keycloak configuration file: no-file.json"); - - //when: - adapterDeploymentContextBean.afterPropertiesSet(); - } - - private Resource getEmptyResource() { - return new ClassPathResource("no-file.json"); - } -} diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBeanTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBeanTest.java new file mode 100644 index 0000000000..6a3b39fd37 --- /dev/null +++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBeanTest.java @@ -0,0 +1,77 @@ +package org.keycloak.adapters.springsecurity; + +import java.io.FileNotFoundException; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.spi.HttpFacade; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import static org.junit.Assert.assertNotNull; + +public class AdapterDeploymentContextFactoryBeanTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private AdapterDeploymentContextFactoryBean adapterDeploymentContextFactoryBean; + + @Test + public void should_create_adapter_deployment_context_from_configuration_file() throws Exception { + // given: + adapterDeploymentContextFactoryBean = new AdapterDeploymentContextFactoryBean(getCorrectResource()); + + // when: + adapterDeploymentContextFactoryBean.afterPropertiesSet(); + + // then + assertNotNull(adapterDeploymentContextFactoryBean.getObject()); + } + + private Resource getCorrectResource() { + return new ClassPathResource("keycloak.json"); + } + + @Test + public void should_throw_exception_when_configuration_file_was_not_found() throws Exception { + // given: + adapterDeploymentContextFactoryBean = new AdapterDeploymentContextFactoryBean(getEmptyResource()); + + // then: + expectedException.expect(FileNotFoundException.class); + expectedException.expectMessage("Unable to locate Keycloak configuration file: no-file.json"); + + // when: + adapterDeploymentContextFactoryBean.afterPropertiesSet(); + } + + private Resource getEmptyResource() { + return new ClassPathResource("no-file.json"); + } + + @Test + public void should_create_adapter_deployment_context_from_keycloak_config_resolver() throws Exception { + // given: + adapterDeploymentContextFactoryBean = new AdapterDeploymentContextFactoryBean(getKeycloakConfigResolver()); + + // when: + adapterDeploymentContextFactoryBean.afterPropertiesSet(); + + // then: + assertNotNull(adapterDeploymentContextFactoryBean.getObject()); + } + + private KeycloakConfigResolver getKeycloakConfigResolver() { + return new KeycloakConfigResolver() { + @Override + public KeycloakDeployment resolve(HttpFacade.Request facade) { + return null; + } + }; + } +} diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java index cc751c4b76..2f44107ba6 100755 --- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java +++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java @@ -2,10 +2,11 @@ package org.keycloak.adapters.springsecurity.authentication; import org.junit.Before; import org.junit.Test; +import org.keycloak.adapters.AdapterDeploymentContext; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.OidcKeycloakAccount; import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean; +import org.keycloak.adapters.spi.HttpFacade; import org.keycloak.adapters.springsecurity.account.KeycloakRole; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.mockito.Mock; @@ -35,7 +36,7 @@ public class KeycloakLogoutHandlerTest { private MockHttpServletResponse response; @Mock - private AdapterDeploymentContextBean adapterDeploymentContextBean; + private AdapterDeploymentContext adapterDeploymentContext; @Mock private OidcKeycloakAccount keycloakAccount; @@ -52,11 +53,11 @@ public class KeycloakLogoutHandlerTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); keycloakAuthenticationToken = mock(KeycloakAuthenticationToken.class); - keycloakLogoutHandler = new KeycloakLogoutHandler(adapterDeploymentContextBean); + keycloakLogoutHandler = new KeycloakLogoutHandler(adapterDeploymentContext); request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); - when(adapterDeploymentContextBean.getDeployment()).thenReturn(keycloakDeployment); + when(adapterDeploymentContext.resolveDeployment(any(HttpFacade.class))).thenReturn(keycloakDeployment); when(keycloakAuthenticationToken.getAccount()).thenReturn(keycloakAccount); when(keycloakAccount.getKeycloakSecurityContext()).thenReturn(session); } diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java index ab4c03258f..1ccc3671b5 100755 --- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java +++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java @@ -4,9 +4,10 @@ import org.junit.Before; import org.junit.Test; import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.AdapterDeploymentContext; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean; +import org.keycloak.adapters.spi.HttpFacade; import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException; import org.keycloak.adapters.springsecurity.account.KeycloakRole; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; @@ -45,7 +46,7 @@ public class KeycloakAuthenticationProcessingFilterTest { private AuthenticationManager authenticationManager; @Mock - private AdapterDeploymentContextBean adapterDeploymentContextBean; + private AdapterDeploymentContext adapterDeploymentContext; @Mock private FilterChain chain; @@ -85,8 +86,8 @@ public class KeycloakAuthenticationProcessingFilterTest { filter.setAuthenticationSuccessHandler(successHandler); filter.setAuthenticationFailureHandler(failureHandler); - when(applicationContext.getBean(eq(AdapterDeploymentContextBean.class))).thenReturn(adapterDeploymentContextBean); - when(adapterDeploymentContextBean.getDeployment()).thenReturn(keycloakDeployment); + when(applicationContext.getBean(eq(AdapterDeploymentContext.class))).thenReturn(adapterDeploymentContext); + when(adapterDeploymentContext.resolveDeployment(any(HttpFacade.class))).thenReturn(keycloakDeployment); when(keycloakAccount.getPrincipal()).thenReturn( new KeycloakPrincipal(UUID.randomUUID().toString(), keycloakSecurityContext)); From b24dfa00094c7ab1f73acfcb6011bc0c671407d7 Mon Sep 17 00:00:00 2001 From: Jean Merelis Date: Sat, 2 Jan 2016 00:37:47 -0200 Subject: [PATCH 2/9] translation of messages to pt_BR --- .../messages/messages_pt_BR.properties | 7 +++- .../login/messages/messages_pt_BR.properties | 33 ++++++++++++++----- .../email/messages/messages_pt_BR.properties | 5 ++- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties index 37c0106632..161ae60b52 100644 --- a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties +++ b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties @@ -52,8 +52,10 @@ role_manage-events=Gerencia eventos role_view-profile=Visualiza perfil role_manage-account=Gerencia conta role_read-token=L\u00EA token +role_offline-access=Acesso Offline client_account=Conta client_security-admin-console=Console de Administra\u00E7\u00E3o de Seguran\u00E7a +client_admin-cli=Admin CLI client_realm-management=Gerenciamento de Realm client_broker=Broker @@ -85,9 +87,11 @@ application=Aplicativo availablePermissions=Permiss\u00F5es Dispon\u00EDveis grantedPermissions=Permiss\u00F5es Concedidas grantedPersonalInfo=Informa\u00E7\u00F5es Pessoais Concedidas +additionalGrants=Concess\u00F5es Adicionais action=A\u00E7\u00E3o inResource=em fullAccess=Acesso Completo +offlineToken=Offline Token revoke=Revogar Concess\u00F5es configureAuthenticators=Autenticadores Configurados @@ -130,6 +134,7 @@ federatedIdentityLinkNotActiveMessage=Esta identidade n\u00E3o est\u00E1 mais em federatedIdentityRemovingLastProviderMessage=Voc\u00EA n\u00E3o pode remover a \u00FAltima identidade federada como voc\u00EA n\u00E3o tem senha identityProviderRedirectErrorMessage=Falha ao redirecionar para o provedor de identidade identityProviderRemovedMessage=Provedor de identidade removido com sucesso +identityProviderAlreadyLinkedMessage=Identidade federada retornado por {0} j\u00E1 est\u00E1 ligado a outro usu\u00E1rio. accountDisabledMessage=Conta desativada, contate o administrador @@ -147,4 +152,4 @@ locale_de=Deutsch locale_en=English locale_it=Italian locale_pt-BR=Portugu\u00EAs (BR) -locale_fr=Fran\u00e7ais \ No newline at end of file +locale_fr=Fran\u00E7ais \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties index a1441202bd..2dbbaf0510 100644 --- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties +++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties @@ -1,4 +1,3 @@ -doLogIn=Entrar doRegister=Cadastre-se doCancel=Cancelar doSubmit=Ok @@ -15,9 +14,9 @@ kerberosNotConfiguredTitle=Kerberos N\u00E3o Configurado bypassKerberosDetail=Ou voc\u00EA n\u00E3o est\u00E1 logado via Kerberos ou o seu navegador n\u00E3o est\u00E1 configurado para login Kerberos. Por favor, clique em continuar para fazer o login no atrav\u00E9s de outros meios kerberosNotSetUp=Kerberos n\u00E3o est\u00E1 configurado. Voc\u00EA n\u00E3o pode acessar. registerWithTitle=Registre-se com {0} -registerWithTitleHtml={0} +registerWithTitleHtml=Registre-se com {0} loginTitle=Entrar em {0} -loginTitleHtml={0} +loginTitleHtml=Entrar em {0} impersonateTitle={0} Impersonate User impersonateTitleHtml={0} Impersonate User realmChoice=Realm @@ -26,7 +25,7 @@ loginTotpTitle=Configura\u00E7\u00E3o do autenticador mobile loginProfileTitle=Atualiza\u00E7\u00E3o das Informa\u00E7\u00F5es da Conta loginTimeout=Voc\u00EA demorou muito para entrar. Por favor, refa\u00E7a o processo de login a partir do in\u00EDcio. oauthGrantTitle=Concess\u00E3o OAuth -oauthGrantTitleHtml={0} +oauthGrantTitleHtml=Acesso tempor\u00E1rio para {0} solicitado pela errorTitle=N\u00F3s lamentamos... errorTitleHtml=N\u00F3s lamentamos ... emailVerifyTitle=Verifica\u00E7\u00E3o de e-mail @@ -79,6 +78,11 @@ emailVerifyInstruction1=Um e-mail com instru\u00E7\u00F5es para verificar o seu emailVerifyInstruction2=Voc\u00EA n\u00E3o recebeu um c\u00F3digo de verifica\u00E7\u00E3o em seu e-mail? emailVerifyInstruction3=para reenviar o e-mail. +emailLinkIdpTitle=Vincular {0} +emailLinkIdp1=Um email com instru\u00E7\u00F5es para vincular a conta {0} {1} com sua conta {2} foi enviado para voc\u00EA. +emailLinkIdp2=N\u00E3o recebeu um c\u00F3digo de verifica\u00E7\u00E3o no e-mail? +emailLinkIdp3=para reenviar o email. + backToLogin=« Voltar emailInstruction=Digite seu nome de usu\u00E1rio ou endere\u00E7o de email e n\u00F3s lhe enviaremos instru\u00E7\u00F5es sobre como criar uma nova senha. @@ -89,6 +93,7 @@ personalInfo=Informa\u00E7\u00F5es Pessoais: role_admin=Admininstrador role_realm-admin=Administra Realm role_create-realm=Cria realm +role_create-client=Cria cliente role_view-realm=Visualiza realm role_view-users=Visualiza usu\u00E1rios role_view-applications=Visualiza aplicativos @@ -104,8 +109,10 @@ role_manage-events=Gerencia eventos role_view-profile=Visualiza perfil role_manage-account=Gerencia contas role_read-token=L\u00EA token +role_offline-access=Acesso offline client_account=Conta client_security-admin-console=Console de Administra\u00E7\u00E3o de Seguran\u00E7a +client_admin-cli=Admin CLI client_realm-management=Gerenciamento de Realm client_broker=Broker @@ -130,13 +137,19 @@ invalidTotpMessage=C\u00F3digo autenticador inv\u00E1lido. usernameExistsMessage=Nome de usu\u00E1rio j\u00E1 existe. emailExistsMessage=Email j\u00E1 existe. -federatedIdentityEmailExistsMessage=J\u00E1 existe usu\u00E1rio com este email. Por favor acesse sua conta de gest\u00E3o para vincular a conta. -federatedIdentityUsernameExistsMessage=J\u00E1 existe usu\u00E1rio com este nome de usu\u00E1rio. Por favor acessar sua conta de gest\u00E3o para vincular a conta. +federatedIdentityExistsMessage=Usu\u00E1rio com {0} {1} j\u00E1 existe. Por favor, entre em gerenciamento de contas para vincular a conta. + +confirmLinkIdpTitle=Conta j\u00E1 existente +federatedIdentityConfirmLinkMessage=Usu\u00E1rio com {0} {1} j\u00E1 existe. Como voc\u00EA quer continuar? +federatedIdentityConfirmReauthenticateMessage=Autenticar como {0} para vincular sua conta com {1} +confirmLinkIdpReviewProfile=Revisar informa\u00E7\u00F5es do perfil +confirmLinkIdpContinue=Vincular {0} com uma conta existente configureTotpMessage=Voc\u00EA precisa configurar seu celular com o autenticador Mobile para ativar sua conta. updateProfileMessage=Voc\u00EA precisa atualizar o seu perfil de usu\u00E1rio para ativar sua conta. updatePasswordMessage=Voc\u00EA precisa mudar sua senha para ativar sua conta. verifyEmailMessage=Voc\u00EA precisa verificar o seu endere\u00E7o de e-mail para ativar sua conta. +linkIdpMessage=Voc\u00EA precisa confirmar o seu endere\u00E7o de e-mail para vincular sua conta com {0}. emailSentMessage=Voc\u00EA dever\u00E1 receber um e-mail em breve com mais instru\u00E7\u00F5es. emailSendErrorMessage=Falha ao enviar e-mail, por favor, tente novamente mais tarde @@ -163,7 +176,8 @@ failedLogout=Falha ao sair unknownLoginRequesterMessage=Solicitante de login desconhecido loginRequesterNotEnabledMessage=Solicitante de login desativado bearerOnlyMessage=Aplicativos somente ao portador n\u00E3o tem permiss\u00E3o para iniciar o login pelo navegador -directGrantsOnlyMessage=Clientes de concess\u00E3o direta n\u00E3o tem permiss\u00E3o para iniciar o login pelo navegador +standardFlowDisabledMessage=Cliente n\u00E3o tem permiss\u00E3o para iniciar o login com response_type informado. O fluxo padr\u00E3o est\u00E1 desabilitado para o cliente. +implicitFlowDisabledMessage=Cliente n\u00E3o tem permiss\u00E3o para iniciar o login com response_type informado. O fluxo padr\u00E3o est\u00E1 desabilitado para o cliente. invalidRedirectUriMessage=URI de redirecionamento inv\u00E1lido unsupportedNameIdFormatMessage=NameIDFormat n\u00E3o suportado invlidRequesterMessage=Solicitante inv\u00E1lido @@ -172,13 +186,13 @@ resetCredentialNotAllowedMessage=Reset Credential not allowed permissionNotApprovedMessage=Permiss\u00E3o n\u00E3o aprovada. noRelayStateInResponseMessage=Sem estado de retransmiss\u00E3o na resposta do provedor de identidade. -identityProviderAlreadyLinkedMessage=A identidade retornado pelo provedor de identidade j\u00E1 est\u00E1 vinculado a outro usu\u00E1rio. insufficientPermissionMessage=Permiss\u00F5es insuficientes para vincular identidades. couldNotProceedWithAuthenticationRequestMessage=N\u00E3o foi poss\u00EDvel proceder \u00E0 solicita\u00E7\u00E3o de autentica\u00E7\u00E3o para provedor de identidade. couldNotObtainTokenMessage=N\u00E3o foi poss\u00EDvel obter token do provedor de identidade. unexpectedErrorRetrievingTokenMessage=Erro inesperado ao recuperar token do provedor de identidade. unexpectedErrorHandlingResponseMessage=Erro inesperado ao manusear resposta do provedor de identidade. identityProviderAuthenticationFailedMessage=Falha na autentica\u00E7\u00E3o. N\u00E3o foi poss\u00EDvel autenticar com o provedor de identidade. +identityProviderDifferentUserMessage=Autenticado como {0}, mas era esperado ser autenticado como {1} couldNotSendAuthenticationRequestMessage=N\u00E3o foi poss\u00EDvel enviar solicita\u00E7\u00E3o de autentica\u00E7\u00E3o para o provedor de identidade. unexpectedErrorHandlingRequestMessage=Erro inesperado ao manusear pedido de autentica\u00E7\u00E3o para provedor de identidade. invalidAccessCodeMessage=C\u00F3digo de acesso inv\u00E1lido. @@ -186,6 +200,7 @@ sessionNotActiveMessage=Sess\u00E3o inativa. invalidCodeMessage=C\u00F3digo inv\u00E1lido, por favor fa\u00E7a login novamente atrav\u00E9s de sua aplica\u00E7\u00E3o. identityProviderUnexpectedErrorMessage=Erro inesperado durante a autentica\u00E7\u00E3o com o provedor de identidade identityProviderNotFoundMessage=N\u00E3o foi poss\u00EDvel encontrar um provedor de identidade com o identificador. +identityProviderLinkSuccess=Sua conta foi vinculada com sucesso com {0} conta {1} . realmSupportsNoCredentialsMessage=O realm n\u00E3o suporta qualquer tipo de credencial. identityProviderNotUniqueMessage=O realm suporta m\u00FAltiplos provedores de identidade. N\u00E3o foi poss\u00EDvel determinar qual o provedor de identidade deve ser usado para se autenticar. emailVerifiedMessage=O seu endere\u00E7o de e-mail foi confirmado. @@ -194,7 +209,7 @@ locale_de=Deutsch locale_en=English locale_it=Italian locale_pt-BR=Portugu\u00EAs (BR) -locale_fr=Fran\u00e7ais +locale_fr=Fran\u00E7ais locale_es=Espa\u00F1ol backToApplication=« Voltar para o aplicativo diff --git a/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties index 06b4647a4c..6596fba771 100755 --- a/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties +++ b/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties @@ -1,6 +1,9 @@ emailVerificationSubject=Verifica\u00E7\u00E3o de e-mail emailVerificationBody=Algu\u00E9m criou uma conta {2} com este endere\u00E7o de e-mail. Se foi voc\u00EA, clique no link abaixo para verificar o seu endere\u00E7o de email\n\n{0}\n\nEste link ir\u00E1 expirar dentro de {1} minutos.\n\nSe n\u00E3o foi voc\u00EA que criou esta conta, basta ignorar esta mensagem. emailVerificationBodyHtml=

Algu\u00E9m criou uma conta {2} com este endere\u00E7o de e-mail. Se foi voc\u00EA, clique no link abaixo para verificar o seu endere\u00E7o de email

{0}

Este link ir\u00E1 expirar dentro de {1} minutos.

Se n\u00E3o foi voc\u00EA que criou esta conta, basta ignorar esta mensagem.

+identityProviderLinkSubject=Vincular {0} +identityProviderLinkBody=Algu\u00E9m quer vincular sua conta "{1}" com a conta "{0}" do usu\u00E1rio {2} . Se foi voc\u00EA, clique no link abaixo para vincular as contas.\n\n{3}\n\nEste link ir\u00E1 expirar em {4} minutos.\n\nSe voc\u00EA n\u00E3o quer vincular a conta, apenas ignore esta mensagem. Se voc\u00EA vincular as contas, voc\u00EA ser\u00E1 capaz de logar em {1} atr\u00E1v\u00E9s de {0}. +identityProviderLinkBodyHtml=

Algu\u00E9m quer vincular sua conta {1} com a conta {0} do usu\u00E1rio {2} . Se foi voc\u00EA, clique no link abaixo para vincular as contas.

{3}

Este link ir\u00E1 expirar em {4} minutos.

Se voc\u00EA n\u00E3o quer vincular a conta, apenas ignore esta mensagem. Se voc\u00EA vincular as contas, voc\u00EA ser\u00E1 capaz de logar em {1} atr\u00E1v\u00E9s de {0}.

passwordResetSubject=Redefini\u00E7\u00E3o de senha passwordResetBody=Someone just requested to change your {2} account''s credentials. If this was you, click on the link below to reset them.\n\n{0}\n\nThis link and code will expire within {1} minutes.\n\nIf you don''t want to reset your credentials, just ignore this message and nothing will be changed. passwordResetBodyHtml=

Someone just requested to change your {2} account''s credentials. If this was you, click on the link below to reset them.

{0}

This link will expire within {1} minutes.

If you don''t want to reset your credentials, just ignore this message and nothing will be changed.

@@ -18,4 +21,4 @@ eventUpdatePasswordBody=Sua senha foi alterada em {0} de {1}. Se n\u00E3o foi vo eventUpdatePasswordBodyHtml=

Sua senha foi alterada em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador.

eventUpdateTotpSubject=Atualiza\u00E7\u00E3o TOTP eventUpdateTotpBody=TOTP foi atualizado para a sua conta em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador. -eventUpdateTotpBodyHtml=

TOTP foi atualizado para a sua conta em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador.

+eventUpdateTotpBodyHtml=

TOTP foi atualizado para a sua conta em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador.

\ No newline at end of file From c5f19ff2b347bf62712aa27c9d3df41ba3b915d4 Mon Sep 17 00:00:00 2001 From: Jean Merelis Date: Sat, 2 Jan 2016 23:23:04 -0200 Subject: [PATCH 3/9] fix some missing translation (pt_BR) --- .../theme/base/login/messages/messages_pt_BR.properties | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties index 2dbbaf0510..d60bb8e10e 100644 --- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties +++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties @@ -1,3 +1,4 @@ +doLogin=Entrar doRegister=Cadastre-se doCancel=Cancelar doSubmit=Ok @@ -38,9 +39,9 @@ termsTitle=Termos e Condi\u00E7\u00F5es termsTitleHtml=Termos e Condi\u00E7\u00F5es termsText=

Termos e Condi\u00E7\u00F5es a ser definido

-recaptchaFailed=Invalid Recaptcha -recaptchaNotConfigured=Recaptcha is required, but not configured -consentDenied=Consent denied. +recaptchaFailed=Recaptcha inv\u00E1lido +recaptchaNotConfigured=Recaptcha \u00E9 requerido, mas n\u00E3o foi configurado +consentDenied=Consentimento negado. noAccount=Novo usu\u00E1rio? username=Nome de usu\u00E1rio @@ -182,7 +183,7 @@ invalidRedirectUriMessage=URI de redirecionamento inv\u00E1lido unsupportedNameIdFormatMessage=NameIDFormat n\u00E3o suportado invlidRequesterMessage=Solicitante inv\u00E1lido registrationNotAllowedMessage=Registro n\u00E3o permitido. -resetCredentialNotAllowedMessage=Reset Credential not allowed +resetCredentialNotAllowedMessage=N\u00E3o \u00E9 permitido redefinir credencial. permissionNotApprovedMessage=Permiss\u00E3o n\u00E3o aprovada. noRelayStateInResponseMessage=Sem estado de retransmiss\u00E3o na resposta do provedor de identidade. From 2fce7f849897cbc8278457e05fcf562958e0864c Mon Sep 17 00:00:00 2001 From: Jean Merelis Date: Sun, 3 Jan 2016 21:02:32 -0200 Subject: [PATCH 4/9] fix doLogIn key (pt_BR) --- .../theme/base/login/messages/messages_pt_BR.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties index d60bb8e10e..58c91c848e 100644 --- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties +++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties @@ -1,4 +1,4 @@ -doLogin=Entrar +doLogIn=Entrar doRegister=Cadastre-se doCancel=Cancelar doSubmit=Ok From cea70337ef9b3ac65be47e6b7ecc4c30deb5b959 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 4 Jan 2016 15:49:57 -0200 Subject: [PATCH 5/9] Tooltips for initial access token fields --- .../theme/base/admin/messages/admin-messages_en.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties index 1fc4e75ed0..0cd4accc7b 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties +++ b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties @@ -492,7 +492,9 @@ client.description.tooltip=Specifies description of the client. For example 'My expires=Expires expiration=Expiration +expiration.tooltip=Specifies how long the token should be valid count=Count +count.tooltip=Specifies how many clients can be created using the token remainingCount=Remaining count created=Created back=Back From 1b857387f26cc7daac15f02f0be11a495fc85d0b Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 4 Jan 2016 15:09:12 -0200 Subject: [PATCH 6/9] Minor change for client registration documentation --- .../reference/en/en-US/modules/client-registration.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml b/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml index fab7119e4f..35f73a3e19 100755 --- a/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml +++ b/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml @@ -193,8 +193,8 @@ String initialAccessToken = "eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJmMjJmNzQyYy04ZjNlLT ClientRepresentation client = new ClientRepresentation(); client.setClientId(CLIENT_ID); -ClientRegistration reg = ClientRegistration.create().url("http://keycloak/auth/realms/myrealm").build(); -reg.auth(initialAccessToken); +ClientRegistration reg = ClientRegistration.create().url("http://keycloak/auth/realms/myrealm/clients").build(); +reg.auth(Auth.token(initialAccessToken)); client = reg.create(client); From 57971ce0b2670b13c189212edf52c3ed842044eb Mon Sep 17 00:00:00 2001 From: Thomas Raehalme Date: Mon, 4 Jan 2016 21:09:36 +0200 Subject: [PATCH 7/9] Changed docs to match the new code. --- .../en/en-US/modules/spring-security-adapter.xml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/spring-security-adapter.xml b/docbook/auth-server-docs/reference/en/en-US/modules/spring-security-adapter.xml index 33c2aa287d..0d3c20c0df 100644 --- a/docbook/auth-server-docs/reference/en/en-US/modules/spring-security-adapter.xml +++ b/docbook/auth-server-docs/reference/en/en-US/modules/spring-security-adapter.xml @@ -115,7 +115,10 @@ public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter - + + + + @@ -124,7 +127,7 @@ public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter - + @@ -157,6 +160,15 @@ public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter +
+ Multi Tenancy + + The Keycloak Spring Security adapter also supports multi tenancy. Instead of injecting + AdapterDeploymentContextFactoryBean with the path to keycloak.json you + can inject an implementation of the KeycloakConfigResolver interface. More details on how + to implement the KeycloakConfigResolver can be found in . + +
Naming Security Roles From 8356409b44258656e588f146948661d74e7b6828 Mon Sep 17 00:00:00 2001 From: Thomas Raehalme Date: Mon, 4 Jan 2016 21:16:37 +0200 Subject: [PATCH 8/9] Fixed some typos in the docs and added paragraph regarding GrantedAuthoritiesMapper. --- .../en/en-US/modules/spring-security-adapter.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/spring-security-adapter.xml b/docbook/auth-server-docs/reference/en/en-US/modules/spring-security-adapter.xml index 0d3c20c0df..dce3d3d899 100644 --- a/docbook/auth-server-docs/reference/en/en-US/modules/spring-security-adapter.xml +++ b/docbook/auth-server-docs/reference/en/en-US/modules/spring-security-adapter.xml @@ -1,7 +1,7 @@
Spring Security Adapter - To to secure an application with Spring Security and Keyloak, add this adapter as a dependency to your project. + To secure an application with Spring Security and Keycloak, add this adapter as a dependency to your project. You then have to provide some extra beans in your Spring Security configuration file and add the Keycloak security filter to your pipeline. @@ -176,6 +176,14 @@ public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter For example, an administrator role must be declared in Keycloak as ROLE_ADMIN or similar, not simply ADMIN. + + The class org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider + supports an optional org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper + which can be used to map roles coming from Keycloak to roles recognized by Spring Security. Use, for example, + org.springframework.security.core.authority.mapping.SimpleAuthorityMapper to insert the + ROLE_ prefix and convert the role name to upper case. The class is part of Spring Security + Core module. +
Client to Client Support From d8d0298498f31c70aeac352180fe3660c5167209 Mon Sep 17 00:00:00 2001 From: Dane Barentine Date: Mon, 4 Jan 2016 11:30:57 -0800 Subject: [PATCH 9/9] KEYCLOAK-2255 Location header should return IdP alias instead of provider ID. --- .../services/resources/admin/IdentityProvidersResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java index bf452ff0f1..84bbdad573 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java @@ -170,7 +170,7 @@ public class IdentityProvidersResource { adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, identityProvider.getInternalId()) .representation(representation).success(); - return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build(); + return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getAlias()).build()).build(); } catch (ModelDuplicateException e) { return ErrorResponse.exists("Identity Provider " + representation.getAlias() + " already exists"); }