diff --git a/adapters/oidc/pom.xml b/adapters/oidc/pom.xml index c563c76887..a2d0691d41 100755 --- a/adapters/oidc/pom.xml +++ b/adapters/oidc/pom.xml @@ -38,7 +38,6 @@ js servlet-filter jakarta-servlet-filter - spring-security undertow wildfly wildfly-elytron diff --git a/adapters/oidc/spring-security/pom.xml b/adapters/oidc/spring-security/pom.xml deleted file mode 100644 index 9dd18395a6..0000000000 --- a/adapters/oidc/spring-security/pom.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - keycloak-parent - org.keycloak - 999.0.0-SNAPSHOT - ../../../pom.xml - - 4.0.0 - - keycloak-spring-security-adapter - Keycloak Spring Security Integration - - - - 5.2.9.RELEASE - 5.2.9.RELEASE - 1.9.5 - 4.3.6 - - - - - org.keycloak - keycloak-core - - - org.keycloak - keycloak-adapter-spi - - - org.keycloak - keycloak-adapter-core - - - org.keycloak - keycloak-policy-enforcer - - - org.jboss.spec.javax.servlet - jboss-servlet-api_4.0_spec - provided - - - org.springframework.security - spring-security-config - ${spring-security.version} - true - compile - - - org.springframework.security - spring-security-web - ${spring-security.version} - true - compile - - - org.slf4j - slf4j-api - compile - - - org.jboss.logging - jboss-logging - compile - - - org.jboss.logging - commons-logging-jboss-logging - runtime - - - org.apache.httpcomponents - httpclient - - - org.bouncycastle - bcprov-jdk18on - runtime - - - com.fasterxml.jackson.core - jackson-core - compile - - - com.fasterxml.jackson.core - jackson-databind - runtime - - - com.fasterxml.jackson.core - jackson-annotations - runtime - - - - org.springframework - spring-test - ${spring.version} - test - - - junit - junit - test - - - org.mockito - mockito-all - ${mockito.version} - test - - - org.slf4j - slf4j-simple - ${slf4j.version} - test - - - diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBean.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBean.java deleted file mode 100644 index 788564a2e1..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBean.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2016 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; - -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; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Objects; - -/** - * {@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/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakAuthenticationException.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakAuthenticationException.java deleted file mode 100644 index 09aef71f8b..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakAuthenticationException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016 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; - -import org.springframework.security.core.AuthenticationException; - -public class KeycloakAuthenticationException extends AuthenticationException { - public KeycloakAuthenticationException(String msg, Throwable t) { - super(msg, t); - } - - public KeycloakAuthenticationException(String msg) { - super(msg); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakConfiguration.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakConfiguration.java deleted file mode 100644 index f434b97baa..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakConfiguration.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.keycloak.adapters.springsecurity; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Add this annotation to a class that extends {@code KeycloakWebSecurityConfigurerAdapter} to provide - * a keycloak based Spring security configuration. - * - * @author Hendrik Ebbers - */ -@Retention(value = RUNTIME) -@Target(value = { TYPE }) -@Configuration -@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) -@EnableWebSecurity -public @interface KeycloakConfiguration { -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakSecurityComponents.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakSecurityComponents.java deleted file mode 100644 index ec26ac3896..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/KeycloakSecurityComponents.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2016 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; - -/** - * Locator interface for Spring context component scanning. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public interface KeycloakSecurityComponents { -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/KeycloakRole.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/KeycloakRole.java deleted file mode 100644 index f83549deb9..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/KeycloakRole.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2016 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.account; - -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.util.Assert; - -/** - * Represents an authority granted to an {@link Authentication} by the Keycloak server. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class KeycloakRole implements GrantedAuthority { - - private String role; - - /** - * Creates a new granted authority from the given Keycloak role. - * - * @param role the name of this granted authority - */ - public KeycloakRole(String role) { - Assert.notNull(role, "role cannot be null"); - this.role = role; - } - - @Override - public String getAuthority() { - return role; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof GrantedAuthority)) { - return false; - } - - GrantedAuthority that = (GrantedAuthority) o; - - if (!role.equals(that.getAuthority())) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 3 * role.hashCode(); - } - - @Override - public String toString() { - return "KeycloakRole{" + - "role='" + role + '\'' + - '}'; - } - -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/SimpleKeycloakAccount.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/SimpleKeycloakAccount.java deleted file mode 100755 index 95a39c6b51..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/SimpleKeycloakAccount.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2016 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.account; - -import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; - -import java.io.Serializable; -import java.security.Principal; -import java.util.Set; - -/** - * Concrete, serializable {@link org.keycloak.adapters.OidcKeycloakAccount} implementation. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class SimpleKeycloakAccount implements OidcKeycloakAccount, Serializable { - - private Set roles; - private Principal principal; - private RefreshableKeycloakSecurityContext securityContext; - - public SimpleKeycloakAccount(Principal principal, Set roles, RefreshableKeycloakSecurityContext securityContext) { - this.principal = principal; - this.roles = roles; - this.securityContext = securityContext; - } - - @Override - public Principal getPrincipal() { - return principal; - } - - @Override - public Set getRoles() { - return roles; - } - - @Override - public RefreshableKeycloakSecurityContext getKeycloakSecurityContext() { - return securityContext; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/HttpHeaderInspectingApiRequestMatcher.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/HttpHeaderInspectingApiRequestMatcher.java deleted file mode 100644 index 3f18a8bf8e..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/HttpHeaderInspectingApiRequestMatcher.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import org.apache.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.security.web.util.matcher.RequestMatcher; - -import javax.servlet.http.HttpServletRequest; - -/** - * {@link RequestMatcher} that determines if a given request is an API request or an - * interactive login request. - * - * @author Scott Rossillo - * @see RequestMatcher - */ -public class HttpHeaderInspectingApiRequestMatcher implements RequestMatcher { - - protected static final String X_REQUESTED_WITH_HEADER = "X-Requested-With"; - protected static final String X_REQUESTED_WITH_HEADER_AJAX_VALUE = "XMLHttpRequest"; - - /** - * Returns true if the given request is an API request or false if it's an interactive - * login request. - * - * @param request the HttpServletRequest - * @return true if the given request is an API request; - * false otherwise - */ - @Override - public boolean matches(HttpServletRequest request) { - return X_REQUESTED_WITH_HEADER_AJAX_VALUE.equals(request.getHeader(X_REQUESTED_WITH_HEADER)); - } - -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationEntryPoint.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationEntryPoint.java deleted file mode 100644 index 95717fc2fb..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationEntryPoint.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.http.HttpHeaders; -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Provides a Keycloak {@link AuthenticationEntryPoint authentication entry point}. Uses a - * {@link RequestMatcher} to determine if the request is an interactive login request or a - * API request, which should not be redirected to an interactive login page. By default, - * this entry point uses a {@link HttpHeaderInspectingApiRequestMatcher} but can be overridden using in the - * constructor. - * - * @author Scott Rossillo - * - * @see HttpHeaderInspectingApiRequestMatcher - */ -public class KeycloakAuthenticationEntryPoint implements AuthenticationEntryPoint { - - /** - * Default Keycloak authentication login URI - */ - public static final String DEFAULT_LOGIN_URI = "/sso/login"; - private static final String DEFAULT_REALM = "Unknown"; - private static final RequestMatcher DEFAULT_API_REQUEST_MATCHER = new HttpHeaderInspectingApiRequestMatcher(); - - private final static Logger log = LoggerFactory.getLogger(KeycloakAuthenticationEntryPoint.class); - - private final RequestMatcher apiRequestMatcher; - private String loginUri = DEFAULT_LOGIN_URI; - private String realm = DEFAULT_REALM; - - private AdapterDeploymentContext adapterDeploymentContext; - - /** - * Creates a new Keycloak authentication entry point. - */ - public KeycloakAuthenticationEntryPoint(AdapterDeploymentContext adapterDeploymentContext) { - this(adapterDeploymentContext, DEFAULT_API_REQUEST_MATCHER); - } - - /** - * Creates a new Keycloak authentication entry point using the given request - * matcher to determine if the current request is an API request or a browser request. - * - * @param apiRequestMatcher the RequestMatcher to use to determine - * if the current request is an API request or a browser request (required) - */ - public KeycloakAuthenticationEntryPoint(AdapterDeploymentContext adapterDeploymentContext, RequestMatcher apiRequestMatcher) { - Assert.notNull(apiRequestMatcher, "apiRequestMatcher required"); - Assert.notNull(adapterDeploymentContext, "adapterDeploymentContext required"); - this.adapterDeploymentContext = adapterDeploymentContext; - this.apiRequestMatcher = apiRequestMatcher; - } - - @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - HttpFacade facade = new SimpleHttpFacade(request, response); - if (apiRequestMatcher.matches(request) || adapterDeploymentContext.resolveDeployment(facade).isBearerOnly()) { - commenceUnauthorizedResponse(request, response); - } else { - commenceLoginRedirect(request, response); - } - } - - /** - * Redirects to the login page. If HTTP sessions are disabled, the redirect URL is saved in a - * cookie now, to be retrieved by the {@link KeycloakAuthenticationSuccessHandler} or the - * {@link KeycloakAuthenticationFailureHandler} when the login sequence completes. - */ - protected void commenceLoginRedirect(HttpServletRequest request, HttpServletResponse response) throws IOException { - if (request.getSession(false) == null && KeycloakCookieBasedRedirect.getRedirectUrlFromCookie(request) == null) { - // If no session exists yet at this point, then apparently the redirect URL is not - // stored in a session. We'll store it in a cookie instead. - response.addCookie(KeycloakCookieBasedRedirect.createCookieFromRedirectUrl(request.getRequestURI())); - } - - String queryParameters = ""; - if (!StringUtils.isEmpty(request.getQueryString())) { - queryParameters = "?" + request.getQueryString(); - } - - String contextAwareLoginUri = request.getContextPath() + loginUri + queryParameters; - log.debug("Redirecting to login URI {}", contextAwareLoginUri); - response.sendRedirect(contextAwareLoginUri); - } - - protected void commenceUnauthorizedResponse(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.addHeader(HttpHeaders.WWW_AUTHENTICATE, String.format("Bearer realm=\"%s\"", realm)); - response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase()); - } - - public void setLoginUri(String loginUri) { - Assert.notNull(loginUri, "loginUri cannot be null"); - this.loginUri = loginUri; - } - - public void setRealm(String realm) { - Assert.notNull(realm, "realm cannot be null"); - this.realm = realm; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationFailureHandler.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationFailureHandler.java deleted file mode 100644 index fdb6cb84c1..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationFailureHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * To return the forbidden code with the corresponding message. - * - * @author emilienbondu - * - */ -public class KeycloakAuthenticationFailureHandler implements AuthenticationFailureHandler { - - @Override - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { - // Check that the response was not committed yet (this may happen when another - // part of the Keycloak adapter sends a challenge or a redirect). - if (!response.isCommitted()) { - if (KeycloakCookieBasedRedirect.getRedirectUrlFromCookie(request) != null) { - response.addCookie(KeycloakCookieBasedRedirect.createCookieFromRedirectUrl(null)); - } - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unable to authenticate using the Authorization header"); - } else { - if (200 <= response.getStatus() && response.getStatus() < 300) { - throw new RuntimeException("Success response was committed while authentication failed!", exception); - } - } - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProvider.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProvider.java deleted file mode 100644 index 1ac6515ea7..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProvider.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import org.keycloak.adapters.springsecurity.account.KeycloakRole; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Performs authentication on a {@link KeycloakAuthenticationToken}. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class KeycloakAuthenticationProvider implements AuthenticationProvider { - private GrantedAuthoritiesMapper grantedAuthoritiesMapper; - - public void setGrantedAuthoritiesMapper(GrantedAuthoritiesMapper grantedAuthoritiesMapper) { - this.grantedAuthoritiesMapper = grantedAuthoritiesMapper; - } - - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication; - List grantedAuthorities = new ArrayList(); - - for (String role : token.getAccount().getRoles()) { - grantedAuthorities.add(new KeycloakRole(role)); - } - return new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), mapAuthorities(grantedAuthorities)); - } - - private Collection mapAuthorities( - Collection authorities) { - return grantedAuthoritiesMapper != null - ? grantedAuthoritiesMapper.mapAuthorities(authorities) - : authorities; - } - - @Override - public boolean supports(Class aClass) { - return KeycloakAuthenticationToken.class.isAssignableFrom(aClass); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationSuccessHandler.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationSuccessHandler.java deleted file mode 100644 index 7a0eab9b6a..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationSuccessHandler.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; - -/** - * Wrapper for an authentication success handler that sends a redirect if a redirect URL was set in - * a cookie. - * - * @author Sjoerd Cranen - * - * @see KeycloakCookieBasedRedirect - * @see KeycloakAuthenticationEntryPoint#commenceLoginRedirect - */ -public class KeycloakAuthenticationSuccessHandler implements AuthenticationSuccessHandler { - - private static final Logger LOG = LoggerFactory.getLogger(KeycloakAuthenticationSuccessHandler.class); - - private final AuthenticationSuccessHandler fallback; - - public KeycloakAuthenticationSuccessHandler(AuthenticationSuccessHandler fallback) { - this.fallback = fallback; - } - - @Override - public void onAuthenticationSuccess( - HttpServletRequest request, HttpServletResponse response, Authentication authentication) - throws IOException, ServletException { - String location = KeycloakCookieBasedRedirect.getRedirectUrlFromCookie(request); - if (location == null) { - if (fallback != null) { - fallback.onAuthenticationSuccess(request, response, authentication); - } - } else { - try { - response.addCookie(KeycloakCookieBasedRedirect.createCookieFromRedirectUrl(null)); - response.sendRedirect(location); - } catch (IOException e) { - LOG.warn("Unable to redirect user after login", e); - } - } - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakCookieBasedRedirect.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakCookieBasedRedirect.java deleted file mode 100644 index b3b8e7e5f7..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakCookieBasedRedirect.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; - -/** - * Utility class that provides methods to create and retrieve cookies used for login redirects. - * - * @author Sjoerd Cranen - */ -public final class KeycloakCookieBasedRedirect { - - private static final String REDIRECT_COOKIE = "KC_REDIRECT"; - - private KeycloakCookieBasedRedirect() {} - - /** - * Checks if a cookie with name {@value REDIRECT_COOKIE} exists, and if so, returns its value. - * If multiple cookies of the same name exist, the value of the first cookie is returned. - * - * @param request the request to retrieve the cookie from. - * @return the value of the cookie, if it exists, or else {@code null}. - */ - public static String getRedirectUrlFromCookie(HttpServletRequest request) { - if (request.getCookies() == null) { - return null; - } - for (Cookie cookie : request.getCookies()) { - if (REDIRECT_COOKIE.equals(cookie.getName())) { - return cookie.getValue(); - } - } - return null; - } - - /** - * Creates a cookie with name {@value REDIRECT_COOKIE} and the given URL as value. - * - * @param url the value that the cookie should have. If {@code null}, a cookie is created that - * expires immediately and has an empty string as value. - * @return a cookie that can be added to a response. - */ - public static Cookie createCookieFromRedirectUrl(String url) { - Cookie cookie = new Cookie(REDIRECT_COOKIE, url == null ? "" : url); - cookie.setHttpOnly(true); - cookie.setPath("/"); - if (url == null) { - cookie.setMaxAge(0); - } - return cookie; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java deleted file mode 100644 index 213788655f..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; -import org.keycloak.adapters.springsecurity.token.AdapterTokenStoreFactory; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.keycloak.adapters.springsecurity.token.SpringSecurityAdapterTokenStoreFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.logout.LogoutHandler; -import org.springframework.util.Assert; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Logs the current user out of Keycloak. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class KeycloakLogoutHandler implements LogoutHandler { - - private static final Logger log = LoggerFactory.getLogger(KeycloakLogoutHandler.class); - - private AdapterDeploymentContext adapterDeploymentContext; - private AdapterTokenStoreFactory adapterTokenStoreFactory = new SpringSecurityAdapterTokenStoreFactory(); - - public KeycloakLogoutHandler(AdapterDeploymentContext adapterDeploymentContext) { - Assert.notNull(adapterDeploymentContext); - this.adapterDeploymentContext = adapterDeploymentContext; - } - - public void setAdapterTokenStoreFactory(AdapterTokenStoreFactory adapterTokenStoreFactory) { - this.adapterTokenStoreFactory = adapterTokenStoreFactory; - } - - @Override - public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { - if (authentication == null) { - log.warn("Cannot log out without authentication"); - return; - } - else if (!KeycloakAuthenticationToken.class.isAssignableFrom(authentication.getClass())) { - log.warn("Cannot log out a non-Keycloak authentication: {}", authentication); - return; - } - - handleSingleSignOut(request, response, (KeycloakAuthenticationToken) authentication); - } - - protected void handleSingleSignOut(HttpServletRequest request, HttpServletResponse response, KeycloakAuthenticationToken authenticationToken) { - HttpFacade facade = new SimpleHttpFacade(request, response); - KeycloakDeployment deployment = adapterDeploymentContext.resolveDeployment(facade); - adapterTokenStoreFactory.createAdapterTokenStore(deployment, request, response).logout(); - RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) authenticationToken.getAccount().getKeycloakSecurityContext(); - session.logout(deployment); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/RequestAuthenticatorFactory.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/RequestAuthenticatorFactory.java deleted file mode 100644 index e640f1b8eb..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/RequestAuthenticatorFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.keycloak.adapters.springsecurity.authentication; - -import javax.servlet.http.HttpServletRequest; - -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.RequestAuthenticator; -import org.keycloak.adapters.spi.HttpFacade; - -/** - * Creates {@link RequestAuthenticator}s. - */ -public interface RequestAuthenticatorFactory { - /** - * Creates new {@link RequestAuthenticator} instances on a per-request basis. - */ - RequestAuthenticator createRequestAuthenticator(HttpFacade facade, HttpServletRequest request, - KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort); -} \ No newline at end of file diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java deleted file mode 100755 index e9b850d992..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import org.keycloak.KeycloakPrincipal; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.AdapterUtils; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.OAuthRequestAuthenticator; -import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.RequestAuthenticator; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.adapters.spi.KeycloakAccount; -import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import java.util.Set; - -/** - * Request authenticator adapter for Spring Security. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class SpringSecurityRequestAuthenticator extends RequestAuthenticator { - - private static final Logger logger = LoggerFactory.getLogger(SpringSecurityRequestAuthenticator.class); - private final HttpServletRequest request; - - /** - * Creates a new Spring Security request authenticator. - * - * @param facade the current HttpFacade (required) - * @param request the current HttpServletRequest (required) - * @param deployment the KeycloakDeployment (required) - * @param tokenStore the AdapterTokenStore (required) - * @param sslRedirectPort the SSL redirect port (required) - */ - public SpringSecurityRequestAuthenticator( - HttpFacade facade, - HttpServletRequest request, - KeycloakDeployment deployment, - AdapterTokenStore tokenStore, - int sslRedirectPort) { - - super(facade, deployment, tokenStore, sslRedirectPort); - this.request = request; - } - - @Override - protected OAuthRequestAuthenticator createOAuthAuthenticator() { - return new OAuthRequestAuthenticator(this, facade, deployment, sslRedirectPort, tokenStore); - } - - @Override - protected void completeOAuthAuthentication(final KeycloakPrincipal principal) { - - final RefreshableKeycloakSecurityContext securityContext = principal.getKeycloakSecurityContext(); - final Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext); - final OidcKeycloakAccount account = new SimpleKeycloakAccount(principal, roles, securityContext); - - request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext); - this.tokenStore.saveAccountInfo(account); - } - - @Override - protected void completeBearerAuthentication(KeycloakPrincipal principal, String method) { - - RefreshableKeycloakSecurityContext securityContext = principal.getKeycloakSecurityContext(); - Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext); - final KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, securityContext); - - logger.debug("Completing bearer authentication. Bearer roles: {} ",roles); - - SecurityContext context = SecurityContextHolder.createEmptyContext(); - context.setAuthentication(new KeycloakAuthenticationToken(account, false)); - SecurityContextHolder.setContext(context); - - request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext); - } - - @Override - protected String changeHttpSessionId(boolean create) { - HttpSession session = request.getSession(create); - return session != null ? session.getId() : null; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorFactory.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorFactory.java deleted file mode 100644 index 15aed06d4d..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorFactory.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.keycloak.adapters.springsecurity.authentication; - -import javax.servlet.http.HttpServletRequest; - -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.RequestAuthenticator; -import org.keycloak.adapters.spi.HttpFacade; - -public class SpringSecurityRequestAuthenticatorFactory implements RequestAuthenticatorFactory { - - @Override - public RequestAuthenticator createRequestAuthenticator(HttpFacade facade, - HttpServletRequest request, KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort) { - return new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, sslRedirectPort); - } -} \ No newline at end of file diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactory.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactory.java deleted file mode 100644 index a5954694e0..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2016 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.client; - -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.HttpClients; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Component; - -/** - * Factory for {@link ClientHttpRequest} objects created for server to server secured - * communication using OAuth2 bearer tokens issued by Keycloak. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class KeycloakClientRequestFactory extends HttpComponentsClientHttpRequestFactory implements ClientHttpRequestFactory { - - public static final String AUTHORIZATION_HEADER = "Authorization"; - - public KeycloakClientRequestFactory() { - super(HttpClients.custom() - .disableCookieManagement() - .build() - ); - } - - @Override - protected void postProcessHttpRequest(HttpUriRequest request) { - KeycloakSecurityContext context = this.getKeycloakSecurityContext(); - request.setHeader(AUTHORIZATION_HEADER, "Bearer " + context.getTokenString()); - } - - /** - * Returns the {@link KeycloakSecurityContext} from the Spring {@link SecurityContextHolder}'s {@link Authentication}. - * - * @return the current KeycloakSecurityContext - */ - protected KeycloakSecurityContext getKeycloakSecurityContext() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - KeycloakAuthenticationToken token; - KeycloakSecurityContext context; - - if (authentication == null) { - throw new IllegalStateException("Cannot set authorization header because there is no authenticated principal"); - } - - if (!KeycloakAuthenticationToken.class.isAssignableFrom(authentication.getClass())) { - throw new IllegalStateException( - String.format( - "Cannot set authorization header because Authentication is of type %s but %s is required", - authentication.getClass(), KeycloakAuthenticationToken.class) - ); - } - - token = (KeycloakAuthenticationToken) authentication; - context = token.getAccount().getKeycloakSecurityContext(); - - return context; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/client/KeycloakRestTemplate.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/client/KeycloakRestTemplate.java deleted file mode 100644 index 7780d59a94..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/client/KeycloakRestTemplate.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2016 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.client; - -import org.springframework.web.client.RestOperations; -import org.springframework.web.client.RestTemplate; - -/** - * Extends Spring's central class for client-side HTTP access, {@link RestTemplate}, adding - * automatic authentication for service to service calls using the currently authenticated Keycloak principal. - * This class is designed to work with other services secured by Keycloak. - * - *

- * The main advantage to using this class over Spring's RestTemplate is that authentication - * is handled automatically when both the service making the API call and the service being called are - * protected by Keycloak authentication. - *

- * - * @see RestOperations - * @see RestTemplate - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class KeycloakRestTemplate extends RestTemplate implements RestOperations { - - /** - * Create a new instance based on the given {@link KeycloakClientRequestFactory}. - * - * @param factory the KeycloakClientRequestFactory to use when creating new requests - */ - public KeycloakRestTemplate(KeycloakClientRequestFactory factory) { - super(factory); - } - -} 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 deleted file mode 100644 index 4fa0bba7f6..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakSpringConfigResolverWrapper.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 Pedro Igor - */ -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; - } - - protected KeycloakConfigResolver getDelegate() { - return 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 deleted file mode 100644 index 034189db1f..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2016 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.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; -import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter; -import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter; -import org.keycloak.adapters.springsecurity.filter.KeycloakCsrfRequestMatcher; -import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter; -import org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter; -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; -import org.springframework.security.config.annotation.web.WebSecurityConfigurer; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.authentication.logout.LogoutFilter; -import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; -import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter; - -/** - * Provides a convenient base class for creating a {@link WebSecurityConfigurer} - * instance secured by Keycloak. This implementation allows customization by overriding methods. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - * @see EnableWebSecurity - * @see EnableWebMvcSecurity - */ -public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter implements WebSecurityConfigurer { - - @Value("${keycloak.configurationFile:WEB-INF/keycloak.json}") - private Resource keycloakConfigFileResource; - @Autowired(required = false) - private KeycloakConfigResolver keycloakConfigResolver; - - @Bean - protected AdapterDeploymentContext adapterDeploymentContext() throws Exception { - AdapterDeploymentContextFactoryBean factoryBean; - if (keycloakConfigResolver != null) { - factoryBean = new AdapterDeploymentContextFactoryBean(new KeycloakSpringConfigResolverWrapper(keycloakConfigResolver)); - } - else { - factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigFileResource); - } - factoryBean.afterPropertiesSet(); - return factoryBean.getObject(); - } - - protected AuthenticationEntryPoint authenticationEntryPoint() throws Exception { - return new KeycloakAuthenticationEntryPoint(adapterDeploymentContext()); - } - - protected KeycloakAuthenticationProvider keycloakAuthenticationProvider() { - return new KeycloakAuthenticationProvider(); - } - - @Bean - protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception { - KeycloakAuthenticationProcessingFilter filter = new KeycloakAuthenticationProcessingFilter(authenticationManagerBean()); - filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy()); - return filter; - } - - @Bean - protected KeycloakPreAuthActionsFilter keycloakPreAuthActionsFilter() { - return new KeycloakPreAuthActionsFilter(httpSessionManager()); - } - - protected KeycloakCsrfRequestMatcher keycloakCsrfRequestMatcher() { - return new KeycloakCsrfRequestMatcher(); - } - - @Bean - protected HttpSessionManager httpSessionManager() { - return new HttpSessionManager(); - } - - protected KeycloakLogoutHandler keycloakLogoutHandler() throws Exception { - return new KeycloakLogoutHandler(adapterDeploymentContext()); - } - - protected abstract SessionAuthenticationStrategy sessionAuthenticationStrategy(); - - @Override - protected void configure(HttpSecurity http) throws Exception { - - http - .csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher()) - .and() - .sessionManagement() - .sessionAuthenticationStrategy(sessionAuthenticationStrategy()) - .and() - .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class) - .addFilterBefore(keycloakAuthenticationProcessingFilter(), LogoutFilter.class) - .addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class) - .addFilterAfter(keycloakAuthenticatedActionsRequestFilter(), KeycloakSecurityContextRequestFilter.class) - .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint()) - .and() - .logout() - .addLogoutHandler(keycloakLogoutHandler()) - .logoutUrl("/sso/logout").permitAll() - .logoutSuccessUrl("/"); - } - - @Bean - protected KeycloakSecurityContextRequestFilter keycloakSecurityContextRequestFilter() { - return new KeycloakSecurityContextRequestFilter(); - } - - @Bean - protected KeycloakAuthenticatedActionsFilter keycloakAuthenticatedActionsRequestFilter() { - return new KeycloakAuthenticatedActionsFilter(); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacade.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacade.java deleted file mode 100755 index 2c9876eace..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacade.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2016 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.facade; - -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.OIDCHttpFacade; -import org.keycloak.adapters.spi.KeycloakAccount; -import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.util.Assert; - -import javax.security.cert.X509Certificate; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Simple {@link org.keycloak.adapters.OIDCHttpFacade} wrapping an {@link HttpServletRequest} and {@link HttpServletResponse}. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class SimpleHttpFacade implements OIDCHttpFacade { - - private final HttpServletRequest request; - private final HttpServletResponse response; - - /** - * Creates a new simple HTTP facade for the given request and response. - * - * @param request the current HttpServletRequest (required) - * @param response the current HttpServletResponse (required) - */ - public SimpleHttpFacade(HttpServletRequest request, HttpServletResponse response) { - Assert.notNull(request, "HttpServletRequest required"); - Assert.notNull(response, "HttpServletResponse required"); - this.request = request; - this.response = response; - } - - @Override - public KeycloakSecurityContext getSecurityContext() { - - SecurityContext context = SecurityContextHolder.getContext(); - - if (context != null && context.getAuthentication() != null) { - KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) context.getAuthentication(); - return authentication.getAccount().getKeycloakSecurityContext(); - } - - return null; - } - - @Override - public Request getRequest() { - return new WrappedHttpServletRequest(request); - } - - @Override - public Response getResponse() { - return new WrappedHttpServletResponse(response); - } - - @Override - public X509Certificate[] getCertificateChain() { - // TODO: implement me - return new X509Certificate[0]; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequest.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequest.java deleted file mode 100755 index f4fa074691..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequest.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2016 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.facade; - -import org.keycloak.adapters.spi.AuthenticationError; -import org.keycloak.adapters.spi.HttpFacade.Cookie; -import org.keycloak.adapters.spi.HttpFacade.Request; -import org.keycloak.adapters.spi.LogoutError; -import org.springframework.util.Assert; - -import javax.servlet.http.HttpServletRequest; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; - -/** - * Concrete Keycloak {@link Request request} implementation wrapping an {@link HttpServletRequest}. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -class WrappedHttpServletRequest implements Request { - - private final HttpServletRequest request; - private InputStream inputStream; - - /** - * Creates a new request for the given HttpServletRequest - * - * @param request the current HttpServletRequest (required) - */ - public WrappedHttpServletRequest(HttpServletRequest request) { - Assert.notNull(request, "HttpServletRequest required"); - this.request = request; - } - - @Override - public String getFirstParam(String param) { - return request.getParameter(param); - } - - @Override - public String getMethod() { - return request.getMethod(); - } - - @Override - public String getURI() { - StringBuffer buf = request.getRequestURL(); - if (request.getQueryString() != null) { - buf.append('?').append(request.getQueryString()); - } - return buf.toString(); - } - - @Override - public String getRelativePath() { - return request.getServletPath(); - } - - @Override - public boolean isSecure() { - return request.isSecure(); - } - - @Override - public String getQueryParamValue(String param) { - return request.getParameter(param); - } - - @Override - public Cookie getCookie(String cookieName) { - - javax.servlet.http.Cookie[] cookies = request.getCookies(); - - if (cookies == null) { - return null; - } - - for (javax.servlet.http.Cookie cookie : request.getCookies()) { - if (cookie.getName().equals(cookieName)) { - return new Cookie(cookie.getName(), cookie.getValue(), cookie.getVersion(), cookie.getDomain(), cookie.getPath()); - } - } - - return null; - } - - @Override - public String getHeader(String name) { - return request.getHeader(name); - } - - @Override - public List getHeaders(String name) { - Enumeration values = request.getHeaders(name); - List array = new ArrayList(); - - while (values.hasMoreElements()) { - array.add(values.nextElement()); - } - - return Collections.unmodifiableList(array); - } - - @Override - public InputStream getInputStream() { - return getInputStream(false); - } - - @Override - public InputStream getInputStream(boolean buffered) { - if (inputStream != null) { - return inputStream; - } - - if (buffered) { - try { - return inputStream = new BufferedInputStream(request.getInputStream()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - try { - return request.getInputStream(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public String getRemoteAddr() { - return request.getRemoteAddr(); - } - - @Override - public void setError(AuthenticationError error) { - request.setAttribute(AuthenticationError.class.getName(), error); - - } - - @Override - public void setError(LogoutError error) { - request.setAttribute(LogoutError.class.getName(), error); - } - - -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponse.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponse.java deleted file mode 100644 index c246e1328a..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponse.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2016 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.facade; - -import org.keycloak.adapters.spi.HttpFacade.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Method; - -/** - * Concrete Keycloak {@link Response response} implementation wrapping an {@link HttpServletResponse}. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -class WrappedHttpServletResponse implements Response { - - private static final Logger log = LoggerFactory.getLogger(WrappedHttpServletResponse.class); - private final HttpServletResponse response; - - /** - * Creates a new response for the given HttpServletResponse. - * - * @param response the current HttpServletResponse (required) - */ - public WrappedHttpServletResponse(HttpServletResponse response) { - this.response = response; - } - - @Override - public void resetCookie(String name, String path) { - Cookie cookie = new Cookie(name, ""); - cookie.setMaxAge(0); - if (path != null) { - cookie.setPath(path); - } - response.addCookie(cookie); - } - - @Override - public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) { - Cookie cookie = new Cookie(name, value); - - if (path != null) { - cookie.setPath(path); - } - - if (domain != null) { - cookie.setDomain(domain); - } - - cookie.setMaxAge(maxAge); - cookie.setSecure(secure); - this.setHttpOnly(cookie, httpOnly); - - response.addCookie(cookie); - } - - private void setHttpOnly(Cookie cookie, boolean httpOnly) { - Method method; - try { - method = Cookie.class.getMethod("setHttpOnly", boolean.class); - method.invoke(cookie, httpOnly); - } catch (NoSuchMethodException e) { - log.warn("Unable to set httpOnly on cookie [{}]; no such method on javax.servlet.http.Cookie", cookie.getName()); - } catch (ReflectiveOperationException e) { - log.error("Unable to set httpOnly on cookie [{}]", cookie.getName(), e); - } - } - - @Override - public void setStatus(int status) { - response.setStatus(status); - } - - @Override - public void addHeader(String name, String value) { - response.addHeader(name, value); - } - - @Override - public void setHeader(String name, String value) { - response.setHeader(name, value); - } - - @Override - public OutputStream getOutputStream() { - try { - return response.getOutputStream(); - } catch (IOException e) { - throw new RuntimeException("Unable to return response output stream", e); - } - } - - @Override - public void sendError(int code) { - try { - response.sendError(code); - } catch (IOException e) { - throw new RuntimeException("Unable to set HTTP status", e); - } - } - - @Override - public void sendError(int code, String message) { - try { - response.sendError(code, message); - } catch (IOException e) { - throw new RuntimeException("Unable to set HTTP status", e); - } - } - - @Override - public void end() { - // TODO: do we need this? - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/package-info.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/package-info.java deleted file mode 100755 index 81b391a9e8..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * Provides an {@link org.keycloak.adapters.OIDCHttpFacade} implementation. - */ -package org.keycloak.adapters.springsecurity.facade; \ No newline at end of file diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/AdapterStateCookieRequestMatcher.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/AdapterStateCookieRequestMatcher.java deleted file mode 100644 index bee9d15000..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/AdapterStateCookieRequestMatcher.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2016 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.filter; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import org.keycloak.constants.AdapterConstants; -import org.springframework.security.web.util.matcher.RequestMatcher; - -/** - * Matches a request if it contains a {@value AdapterConstants#KEYCLOAK_ADAPTER_STATE_COOKIE} - * cookie. - * - * @author Sjoerd Cranen - */ -public class AdapterStateCookieRequestMatcher implements RequestMatcher { - - @Override - public boolean matches(HttpServletRequest request) { - if (request.getCookies() == null) { - return false; - } - for (Cookie cookie: request.getCookies()) { - if (AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE.equals(cookie.getName())) { - return true; - } - } - return false; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticatedActionsFilter.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticatedActionsFilter.java deleted file mode 100644 index 3ef324fa4e..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticatedActionsFilter.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.filter; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.keycloak.KeycloakPrincipal; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.AuthenticatedActionsHandler; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.OIDCHttpFacade; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.GenericFilterBean; - -/** - * @author Pedro Igor - */ -public class KeycloakAuthenticatedActionsFilter extends GenericFilterBean implements ApplicationContextAware { - - private static final String FILTER_APPLIED = KeycloakAuthenticatedActionsFilter.class.getPackage().getName() + ".authenticated-actions"; - - private ApplicationContext applicationContext; - private AdapterDeploymentContext deploymentContext; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { - if (request.getAttribute(FILTER_APPLIED) != null) { - filterChain.doFilter(request, response); - return; - } - - request.setAttribute(FILTER_APPLIED, Boolean.TRUE); - - KeycloakSecurityContext keycloakSecurityContext = getKeycloakPrincipal(); - - if (keycloakSecurityContext instanceof RefreshableKeycloakSecurityContext) { - HttpFacade facade = new SimpleHttpFacade((HttpServletRequest) request, (HttpServletResponse) response); - KeycloakDeployment deployment = resolveDeployment(request, response); - AuthenticatedActionsHandler actions = new AuthenticatedActionsHandler(deployment, OIDCHttpFacade.class.cast(facade)); - if (actions.handledRequest()) { - return; - } - } - - filterChain.doFilter(request, response); - } - - @Override - protected void initFilterBean() { - deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class); - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - private KeycloakSecurityContext getKeycloakPrincipal() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - - if (authentication != null) { - Object principal = authentication.getPrincipal(); - - if (principal instanceof KeycloakPrincipal) { - return KeycloakPrincipal.class.cast(principal).getKeycloakSecurityContext(); - } - } - - return null; - } - - private KeycloakDeployment resolveDeployment(ServletRequest servletRequest, ServletResponse servletResponse) { - return deploymentContext.resolveDeployment(new SimpleHttpFacade(HttpServletRequest.class.cast(servletRequest), HttpServletResponse.class.cast(servletResponse))); - } - - private void clearAuthenticationContext() { - SecurityContextHolder.clearContext(); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java deleted file mode 100644 index 930867efd6..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2016 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.filter; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.keycloak.OAuth2Constants; -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.RequestAuthenticator; -import org.keycloak.adapters.spi.AuthChallenge; -import org.keycloak.adapters.spi.AuthOutcome; -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.KeycloakAuthenticationFailureHandler; -import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationSuccessHandler; -import org.keycloak.adapters.springsecurity.authentication.RequestAuthenticatorFactory; -import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticatorFactory; -import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; -import org.keycloak.adapters.springsecurity.token.AdapterTokenStoreFactory; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.keycloak.adapters.springsecurity.token.SpringSecurityAdapterTokenStoreFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.OrRequestMatcher; -import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.Assert; - -/** - * Provides a Keycloak authentication processing filter. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter implements ApplicationContextAware { - public static final String AUTHORIZATION_HEADER = "Authorization"; - - /** - * Request matcher that matches requests to the {@link KeycloakAuthenticationEntryPoint#DEFAULT_LOGIN_URI default login URI} - * and any request with a Authorization header or an {@link AdapterStateCookieRequestMatcher adapter state cookie}. - */ - public static final RequestMatcher DEFAULT_REQUEST_MATCHER = - new OrRequestMatcher( - new AntPathRequestMatcher(KeycloakAuthenticationEntryPoint.DEFAULT_LOGIN_URI), - new RequestHeaderRequestMatcher(AUTHORIZATION_HEADER), - new QueryParamPresenceRequestMatcher(OAuth2Constants.ACCESS_TOKEN), - new AdapterStateCookieRequestMatcher() - ); - - private static final Logger log = LoggerFactory.getLogger(KeycloakAuthenticationProcessingFilter.class); - - private ApplicationContext applicationContext; - private AdapterDeploymentContext adapterDeploymentContext; - private AdapterTokenStoreFactory adapterTokenStoreFactory = new SpringSecurityAdapterTokenStoreFactory(); - private AuthenticationManager authenticationManager; - private RequestAuthenticatorFactory requestAuthenticatorFactory = new SpringSecurityRequestAuthenticatorFactory(); - - /** - * Creates a new Keycloak authentication processing filter with given {@link AuthenticationManager} and the - * {@link KeycloakAuthenticationProcessingFilter#DEFAULT_REQUEST_MATCHER default request matcher}. - * - * @param authenticationManager the {@link AuthenticationManager} to authenticate requests (cannot be null) - * @see KeycloakAuthenticationProcessingFilter#DEFAULT_REQUEST_MATCHER - */ - public KeycloakAuthenticationProcessingFilter(AuthenticationManager authenticationManager) { - this(authenticationManager, DEFAULT_REQUEST_MATCHER); - setAuthenticationFailureHandler(new KeycloakAuthenticationFailureHandler()); - setAuthenticationSuccessHandler(new KeycloakAuthenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler())); - } - - /** - * Creates a new Keycloak authentication processing filter with given {@link AuthenticationManager} and - * {@link RequestMatcher}. - *

- * Note: the given request matcher must support matching the Authorization header if - * bearer token authentication is to be accepted. - *

- * - * @param authenticationManager the {@link AuthenticationManager} to authenticate requests (cannot be null) - * @param requiresAuthenticationRequestMatcher the {@link RequestMatcher} used to determine if authentication - * is required (cannot be null) - * - * @see RequestHeaderRequestMatcher - * @see OrRequestMatcher - * - */ - public KeycloakAuthenticationProcessingFilter(AuthenticationManager authenticationManager, RequestMatcher - requiresAuthenticationRequestMatcher) { - super(requiresAuthenticationRequestMatcher); - Assert.notNull(authenticationManager, "authenticationManager cannot be null"); - this.authenticationManager = authenticationManager; - super.setAuthenticationManager(authenticationManager); - super.setAllowSessionCreation(false); - super.setContinueChainBeforeSuccessfulAuthentication(false); - } - - @Override - public void afterPropertiesSet() { - adapterDeploymentContext = applicationContext.getBean(AdapterDeploymentContext.class); - super.afterPropertiesSet(); - } - - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) - throws AuthenticationException, IOException, ServletException { - - log.debug("Attempting Keycloak authentication"); - - HttpFacade facade = new SimpleHttpFacade(request, response); - KeycloakDeployment deployment = adapterDeploymentContext.resolveDeployment(facade); - - // using Spring authenticationFailureHandler - deployment.setDelegateBearerErrorResponseSending(true); - - AdapterTokenStore tokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, request, response); - RequestAuthenticator authenticator - = requestAuthenticatorFactory.createRequestAuthenticator(facade, request, deployment, tokenStore, -1); - - AuthOutcome result = authenticator.authenticate(); - log.debug("Auth outcome: {}", result); - - if (AuthOutcome.FAILED.equals(result)) { - AuthChallenge challenge = authenticator.getChallenge(); - if (challenge != null) { - challenge.challenge(facade); - } - throw new KeycloakAuthenticationException("Invalid authorization header, see WWW-Authenticate header for details"); - } - - if (AuthOutcome.NOT_ATTEMPTED.equals(result)) { - AuthChallenge challenge = authenticator.getChallenge(); - if (challenge != null) { - challenge.challenge(facade); - } - if (deployment.isBearerOnly()) { - // no redirection in this mode, throwing exception for the spring handler - throw new KeycloakAuthenticationException("Authorization header not found, see WWW-Authenticate header"); - } else { - // let continue if challenged, it may redirect - return null; - } - } - - else if (AuthOutcome.AUTHENTICATED.equals(result)) { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - Assert.notNull(authentication, "Authentication SecurityContextHolder was null"); - return authenticationManager.authenticate(authentication); - } - else { - AuthChallenge challenge = authenticator.getChallenge(); - if (challenge != null) { - challenge.challenge(facade); - } - return null; - } - } - - @Override - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, - Authentication authResult) throws IOException, ServletException { - if (authResult instanceof KeycloakAuthenticationToken && ((KeycloakAuthenticationToken) authResult).isInteractive()) { - super.successfulAuthentication(request, response, chain, authResult); - return; - } - - if (log.isDebugEnabled()) { - log.debug("Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: {}", authResult); - } - - SecurityContext context = SecurityContextHolder.createEmptyContext(); - context.setAuthentication(authResult); - SecurityContextHolder.setContext(context); - - try { - // Fire event - if (this.eventPublisher != null) { - eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass())); - } - chain.doFilter(request, response); - } finally { - SecurityContextHolder.clearContext(); - } - } - - @Override - protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, - AuthenticationException failed) throws IOException, ServletException { - super.unsuccessfulAuthentication(request, response, failed); - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - /** - * Sets the adapter token store factory to use when creating per-request adapter token stores. - * - * @param adapterTokenStoreFactory the AdapterTokenStoreFactory to use - */ - public void setAdapterTokenStoreFactory(AdapterTokenStoreFactory adapterTokenStoreFactory) { - Assert.notNull(adapterTokenStoreFactory, "AdapterTokenStoreFactory cannot be null"); - this.adapterTokenStoreFactory = adapterTokenStoreFactory; - } - - /** - * This filter does not support explicitly enabling session creation. - * - * @throws UnsupportedOperationException this filter does not support explicitly enabling session creation. - */ - @Override - public final void setAllowSessionCreation(boolean allowSessionCreation) { - throw new UnsupportedOperationException("This filter does not support explicitly setting a session creation policy"); - } - - /** - * This filter does not support explicitly setting a continue chain before success policy - * - * @throws UnsupportedOperationException this filter does not support explicitly setting a continue chain before success policy - */ - @Override - public final void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) { - throw new UnsupportedOperationException("This filter does not support explicitly setting a continue chain before success policy"); - } - - /** - * Sets the request authenticator factory to use when creating per-request authenticators. - * - * @param requestAuthenticatorFactory the RequestAuthenticatorFactory to use - */ - public void setRequestAuthenticatorFactory(RequestAuthenticatorFactory requestAuthenticatorFactory) { - Assert.notNull(requestAuthenticatorFactory, "RequestAuthenticatorFactory cannot be null"); - this.requestAuthenticatorFactory = requestAuthenticatorFactory; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakCsrfRequestMatcher.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakCsrfRequestMatcher.java deleted file mode 100644 index 93a48f5737..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakCsrfRequestMatcher.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2016 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.filter; - -import org.keycloak.constants.AdapterConstants; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.StringUtils; - -import javax.servlet.http.HttpServletRequest; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; - -/** - * CSRF protection matcher that allows administrative POST requests from the Keycloak server. - * - * @author Scott Rossillo - */ -public class KeycloakCsrfRequestMatcher implements RequestMatcher { - - private static final List ALLOWED_ENDPOINTS = Arrays.asList( - AdapterConstants.K_LOGOUT, - AdapterConstants.K_PUSH_NOT_BEFORE, - AdapterConstants.K_QUERY_BEARER_TOKEN, - AdapterConstants.K_TEST_AVAILABLE - ); - - private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$"); - private Pattern allowedEndpoints = Pattern.compile(String.format("^\\/(%s)$", StringUtils.arrayToDelimitedString(ALLOWED_ENDPOINTS.toArray(), "|"))); - - /* (non-Javadoc) - * @see org.springframework.security.web.util.matcher.RequestMatcher#matches(javax.servlet.http.HttpServletRequest) - */ - public boolean matches(HttpServletRequest request) { - String uri = request.getRequestURI().replaceFirst(request.getContextPath(), ""); - return !allowedEndpoints.matcher(uri).matches() && !allowedMethods.matcher(request.getMethod()).matches(); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java deleted file mode 100755 index 75bc815f27..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2016 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.filter; - -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.NodesRegistrationManagement; -import org.keycloak.adapters.PreAuthActionsHandler; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.adapters.spi.UserSessionManagement; -import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.web.filter.GenericFilterBean; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * Exposes a Keycloak adapter {@link PreAuthActionsHandler} as a Spring Security filter. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class KeycloakPreAuthActionsFilter extends GenericFilterBean implements ApplicationContextAware { - - private static final Logger log = LoggerFactory.getLogger(KeycloakPreAuthActionsFilter.class); - - private NodesRegistrationManagement nodesRegistrationManagement = new NodesRegistrationManagement(); - private ApplicationContext applicationContext; - private AdapterDeploymentContext deploymentContext; - private UserSessionManagement userSessionManagement; - private PreAuthActionsHandlerFactory preAuthActionsHandlerFactory = new PreAuthActionsHandlerFactory(); - - public KeycloakPreAuthActionsFilter() { - super(); - } - - public KeycloakPreAuthActionsFilter(UserSessionManagement userSessionManagement) { - this.userSessionManagement = userSessionManagement; - } - - @Override - protected void initFilterBean() throws ServletException { - deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class); - } - - @Override - public void destroy() { - log.debug("Unregistering deployment"); - nodesRegistrationManagement.stop(); - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - - HttpFacade facade = new SimpleHttpFacade((HttpServletRequest)request, (HttpServletResponse)response); - KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade); - - if (deployment == null) { - return; - } - - if (deployment.isConfigured()) { - nodesRegistrationManagement.tryRegister(deploymentContext.resolveDeployment(facade)); - } - - PreAuthActionsHandler handler = preAuthActionsHandlerFactory.createPreAuthActionsHandler(facade); - if (handler.handleRequest()) { - log.debug("Pre-auth filter handled request: {}", ((HttpServletRequest) request).getRequestURI()); - } else { - chain.doFilter(request, response); - } - } - - public void setUserSessionManagement(UserSessionManagement userSessionManagement) { - this.userSessionManagement = userSessionManagement; - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - void setNodesRegistrationManagement(NodesRegistrationManagement nodesRegistrationManagement) { - this.nodesRegistrationManagement = nodesRegistrationManagement; - } - - void setPreAuthActionsHandlerFactory(PreAuthActionsHandlerFactory preAuthActionsHandlerFactory) { - this.preAuthActionsHandlerFactory = preAuthActionsHandlerFactory; - } - - /** - * Creates {@link PreAuthActionsHandler}s. - * - * Package-private class to enable mocking. - */ - class PreAuthActionsHandlerFactory { - PreAuthActionsHandler createPreAuthActionsHandler(HttpFacade facade) { - return new PreAuthActionsHandler(userSessionManagement, deploymentContext, facade); - } - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakSecurityContextRequestFilter.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakSecurityContextRequestFilter.java deleted file mode 100644 index 4e17183ad3..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakSecurityContextRequestFilter.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2017 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.filter; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.keycloak.KeycloakPrincipal; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; -import org.keycloak.adapters.springsecurity.token.AdapterTokenStoreFactory; -import org.keycloak.adapters.springsecurity.token.SpringSecurityAdapterTokenStoreFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.GenericFilterBean; - -/** - * @author Pedro Igor - */ -public class KeycloakSecurityContextRequestFilter extends GenericFilterBean implements ApplicationContextAware { - private static final Logger log = LoggerFactory.getLogger(KeycloakSecurityContextRequestFilter.class); - - private static final String FILTER_APPLIED = KeycloakSecurityContext.class.getPackage().getName() + ".token-refreshed"; - private final AdapterTokenStoreFactory adapterTokenStoreFactory = new SpringSecurityAdapterTokenStoreFactory(); - - private ApplicationContext applicationContext; - private AdapterDeploymentContext deploymentContext; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { - if (request.getAttribute(FILTER_APPLIED) != null) { - filterChain.doFilter(request, response); - return; - } - - request.setAttribute(FILTER_APPLIED, Boolean.TRUE); - - KeycloakSecurityContext keycloakSecurityContext = getKeycloakSecurityContext(); - - if (keycloakSecurityContext instanceof RefreshableKeycloakSecurityContext) { - RefreshableKeycloakSecurityContext refreshableSecurityContext = (RefreshableKeycloakSecurityContext) keycloakSecurityContext; - KeycloakDeployment deployment = resolveDeployment(request, response); - - // just in case session got serialized - if (refreshableSecurityContext.getDeployment()==null) { - log.trace("Recreating missing deployment and related fields in deserialized context"); - AdapterTokenStore adapterTokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, (HttpServletRequest) request, - (HttpServletResponse) response); - refreshableSecurityContext.setCurrentRequestInfo(deployment, adapterTokenStore); - } - - if (!refreshableSecurityContext.isActive() || deployment.isAlwaysRefreshToken()) { - if (refreshableSecurityContext.refreshExpiredToken(false)) { - request.setAttribute(KeycloakSecurityContext.class.getName(), refreshableSecurityContext); - } else { - clearAuthenticationContext(); - } - } - - request.setAttribute(KeycloakSecurityContext.class.getName(), keycloakSecurityContext); - } - - filterChain.doFilter(request, response); - } - - @Override - protected void initFilterBean() { - deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class); - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - private KeycloakSecurityContext getKeycloakSecurityContext() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - - if (authentication != null) { - Object principal = authentication.getPrincipal(); - - if (principal instanceof KeycloakPrincipal) { - return KeycloakPrincipal.class.cast(principal).getKeycloakSecurityContext(); - } - } - - return null; - } - - private KeycloakDeployment resolveDeployment(ServletRequest servletRequest, ServletResponse servletResponse) { - return deploymentContext.resolveDeployment(new SimpleHttpFacade(HttpServletRequest.class.cast(servletRequest), HttpServletResponse.class.cast(servletResponse))); - } - - private void clearAuthenticationContext() { - SecurityContextHolder.clearContext(); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/QueryParamPresenceRequestMatcher.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/QueryParamPresenceRequestMatcher.java deleted file mode 100644 index 76164638e9..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/QueryParamPresenceRequestMatcher.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2017 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.filter; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.security.web.util.matcher.RequestMatcher; - -/** - * Spring RequestMatcher that checks for the presence of a query parameter. - * - * @author Gabriel Lavoie - */ -public class QueryParamPresenceRequestMatcher implements RequestMatcher { - private String param; - - public QueryParamPresenceRequestMatcher(String param) { - this.param = param; - } - - @Override - public boolean matches(HttpServletRequest httpServletRequest) { - return param != null && httpServletRequest.getParameter(param) != null; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/package-info.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/package-info.java deleted file mode 100644 index c0b3c9aea9..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * Provides Spring Security filters for Keycloak. - */ -package org.keycloak.adapters.springsecurity.filter; \ No newline at end of file diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/HttpSessionManager.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/HttpSessionManager.java deleted file mode 100644 index f711b3919d..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/HttpSessionManager.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2016 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.management; - -import java.util.List; - -import javax.servlet.http.HttpSession; - -import org.keycloak.adapters.spi.UserSessionManagement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.security.web.session.HttpSessionCreatedEvent; -import org.springframework.security.web.session.HttpSessionDestroyedEvent; - -/** - * User session manager for handling logout of Spring Secured sessions. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class HttpSessionManager implements ApplicationListener, UserSessionManagement { - - private static final Logger log = LoggerFactory.getLogger(HttpSessionManager.class); - private SessionManagementStrategy sessions = new LocalSessionManagementStrategy(); - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof HttpSessionCreatedEvent) { - HttpSessionCreatedEvent e = (HttpSessionCreatedEvent) event; - HttpSession session = e.getSession(); - log.debug("Session created: {}", session.getId()); - sessions.store(session); - } else if (event instanceof HttpSessionDestroyedEvent) { - HttpSessionDestroyedEvent e = (HttpSessionDestroyedEvent) event; - HttpSession session = e.getSession(); - sessions.remove(session.getId()); - log.debug("Session destroyed: {}", session.getId()); - } - } - - @Override - public void logoutAll() { - log.info("Received request to log out all users."); - for (HttpSession session : sessions.getAll()) { - session.invalidate(); - } - sessions.clear(); - } - - @Override - public void logoutHttpSessions(List ids) { - log.info("Received request to log out {} session(s): {}", ids.size(), ids); - for (String id : ids) { - HttpSession session = sessions.remove(id); - if (session != null) { - session.invalidate(); - } - } - } - -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/LocalSessionManagementStrategy.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/LocalSessionManagementStrategy.java deleted file mode 100644 index 7487ac5f51..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/LocalSessionManagementStrategy.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2016 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.management; - -import javax.servlet.http.HttpSession; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Created by scott on 4/24/15. - */ -public class LocalSessionManagementStrategy implements SessionManagementStrategy { - - private final Map sessions = new ConcurrentHashMap(); - - @Override - public void clear() { - sessions.clear(); - } - - @Override - public Collection getAll() { - return sessions.values(); - } - - @Override - public void store(HttpSession session) { - sessions.put(session.getId(), session); - } - - @Override - public HttpSession remove(String id) { - return sessions.remove(id); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/SessionManagementStrategy.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/SessionManagementStrategy.java deleted file mode 100644 index b39ca1b562..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/management/SessionManagementStrategy.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2016 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.management; - -import javax.servlet.http.HttpSession; -import java.util.Collection; - -/** - * Defines a session management strategy. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public interface SessionManagementStrategy { - - /** - * Removes all sessions. - */ - void clear(); - - /** - * Returns a collection containing all sessions. - * - * @return a Collection of all known HttpSessions, if any; - * an empty Collection otherwise - */ - Collection getAll(); - - /** - * Stores the given session. - * - * @param session the HttpSession to store (required) - */ - void store(HttpSession session); - - /** - * The unique identifier for the session to remove. - * - * @param id the unique identifier for the session to remove (required) - * @return the HttpSession if it exists; null otherwise - */ - HttpSession remove(String id); -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/package-info.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/package-info.java deleted file mode 100644 index b3b990e05f..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * Provides a Keycloak adapter for Spring Security. - */ -package org.keycloak.adapters.springsecurity; \ No newline at end of file diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/registration/NodeManager.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/registration/NodeManager.java deleted file mode 100644 index 6a7680cc84..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/registration/NodeManager.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2016 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.registration; - -import org.keycloak.adapters.KeycloakDeployment; - -/** - * Manages registration of application nodes. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public interface NodeManager { - - /** - * Registers the given deployment with the Keycloak server. - * - * @param deployment the deployment to register (required) - */ - void register(KeycloakDeployment deployment); - - /** - * Unregisters the give deployment from the Keycloak server - * . - * @param deployment the deployment to unregister (required) - */ - void unregister(KeycloakDeployment deployment); - -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/AdapterTokenStoreFactory.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/AdapterTokenStoreFactory.java deleted file mode 100644 index b8a60ce7d2..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/AdapterTokenStoreFactory.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2016 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.token; - -import javax.servlet.http.HttpServletResponse; -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.KeycloakDeployment; - -import javax.servlet.http.HttpServletRequest; - -/** - * Creates a per-request adapter token store. - * - * @author Scott Rossillo - */ -public interface AdapterTokenStoreFactory { - - /** - * Returns a new {@link AdapterTokenStore} for the given {@link KeycloakDeployment} and {@link HttpServletRequest request}. - * - * @param deployment the KeycloakDeployment (required) - * @param request the current HttpServletRequest (required) - * @param response the current HttpServletResponse (required when using cookies) - * - * @return a new AdapterTokenStore for the given deployment, request and response - * @throws IllegalArgumentException if any required parameter is null - */ - AdapterTokenStore createAdapterTokenStore(KeycloakDeployment deployment, HttpServletRequest request, HttpServletResponse response); - -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/KeycloakAuthenticationToken.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/KeycloakAuthenticationToken.java deleted file mode 100755 index fad2782c30..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/KeycloakAuthenticationToken.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016 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.token; - -import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.spi.KeycloakAccount; -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.util.Assert; - -import java.security.Principal; -import java.util.Collection; - -/** - * Represents the token for a Keycloak authentication request or for an authenticated principal once the request has been - * processed by the {@link AuthenticationManager#authenticate(Authentication)}. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class KeycloakAuthenticationToken extends AbstractAuthenticationToken implements Authentication { - - private Principal principal; - private boolean interactive; - - /** - * Creates a new, unauthenticated Keycloak security token for the given account. - */ - public KeycloakAuthenticationToken(KeycloakAccount account, boolean interactive) { - super(null); - Assert.notNull(account, "KeycloakAccount cannot be null"); - Assert.notNull(account.getPrincipal(), "KeycloakAccount.getPrincipal() cannot be null"); - this.principal = account.getPrincipal(); - this.setDetails(account); - this.interactive = interactive; - } - - public KeycloakAuthenticationToken(KeycloakAccount account, boolean interactive, Collection authorities) { - super(authorities); - Assert.notNull(account, "KeycloakAccount cannot be null"); - Assert.notNull(account.getPrincipal(), "KeycloakAccount.getPrincipal() cannot be null"); - this.principal = account.getPrincipal(); - this.setDetails(account); - this.interactive = interactive; - setAuthenticated(true); - } - - @Override - public Object getCredentials() { - return this.getAccount().getKeycloakSecurityContext(); - } - - @Override - public Object getPrincipal() { - return principal; - } - - public OidcKeycloakAccount getAccount() { - return (OidcKeycloakAccount) this.getDetails(); - } - - public boolean isInteractive() { - return interactive; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityAdapterTokenStoreFactory.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityAdapterTokenStoreFactory.java deleted file mode 100644 index 321744cede..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityAdapterTokenStoreFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2016 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.token; - -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.enums.TokenStore; -import org.springframework.util.Assert; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * {@link AdapterTokenStoreFactory} that returns a new {@link SpringSecurityTokenStore} for each request. - * - * @author Scott Rossillo - */ -public class SpringSecurityAdapterTokenStoreFactory implements AdapterTokenStoreFactory { - - @Override - public AdapterTokenStore createAdapterTokenStore(KeycloakDeployment deployment, HttpServletRequest request, HttpServletResponse response) { - Assert.notNull(deployment, "KeycloakDeployment is required"); - if (deployment.getTokenStore() == TokenStore.COOKIE) { - return new SpringSecurityCookieTokenStore(deployment, request, response); - } - return new SpringSecurityTokenStore(deployment, request); - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityCookieTokenStore.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityCookieTokenStore.java deleted file mode 100644 index 92699f82b4..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityCookieTokenStore.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2016 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.token; - -import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.keycloak.KeycloakPrincipal; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.AdapterUtils; -import org.keycloak.adapters.CookieTokenStore; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.OIDCHttpFacade; -import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.RequestAuthenticator; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount; -import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.util.Assert; - -/** - * Extension of {@link SpringSecurityTokenStore} that stores the obtains tokens in a cookie. - * - * @author Sjoerd Cranen - */ -public class SpringSecurityCookieTokenStore extends SpringSecurityTokenStore { - - private final Logger logger = LoggerFactory.getLogger(SpringSecurityCookieTokenStore.class); - - private final KeycloakDeployment deployment; - private final HttpFacade facade; - private volatile boolean cookieChecked = false; - - public SpringSecurityCookieTokenStore( - KeycloakDeployment deployment, - HttpServletRequest request, - HttpServletResponse response) { - super(deployment, request); - Assert.notNull(response, "HttpServletResponse is required"); - this.deployment = deployment; - this.facade = new SimpleHttpFacade(request, response); - } - - @Override - public void checkCurrentToken() { - final KeycloakPrincipal principal = - checkPrincipalFromCookie(); - if (principal != null) { - final RefreshableKeycloakSecurityContext securityContext = - principal.getKeycloakSecurityContext(); - KeycloakSecurityContext current = ((OIDCHttpFacade) facade).getSecurityContext(); - if (current != null) { - securityContext.setAuthorizationContext(current.getAuthorizationContext()); - } - final Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext); - final OidcKeycloakAccount account = - new SimpleKeycloakAccount(principal, roles, securityContext); - SecurityContextHolder.getContext() - .setAuthentication(new KeycloakAuthenticationToken(account, false)); - } else { - super.checkCurrentToken(); - } - cookieChecked = true; - } - - @Override - public boolean isCached(RequestAuthenticator authenticator) { - if (!cookieChecked) { - checkCurrentToken(); - } - return super.isCached(authenticator); - } - - @Override - public void refreshCallback(RefreshableKeycloakSecurityContext securityContext) { - super.refreshCallback(securityContext); - CookieTokenStore.setTokenCookie(deployment, facade, securityContext); - } - - @Override - public void saveAccountInfo(OidcKeycloakAccount account) { - super.saveAccountInfo(account); - RefreshableKeycloakSecurityContext securityContext = - (RefreshableKeycloakSecurityContext) account.getKeycloakSecurityContext(); - CookieTokenStore.setTokenCookie(deployment, facade, securityContext); - } - - @Override - public void logout() { - CookieTokenStore.removeCookie(deployment, facade); - super.logout(); - } - - /** - * Verify if we already have authenticated and active principal in cookie. Perform refresh if - * it's not active - * - * @return valid principal - */ - private KeycloakPrincipal checkPrincipalFromCookie() { - KeycloakPrincipal principal = - CookieTokenStore.getPrincipalFromCookie(deployment, facade, this); - if (principal == null) { - logger.debug("Account was not in cookie or was invalid"); - return null; - } - - RefreshableKeycloakSecurityContext session = principal.getKeycloakSecurityContext(); - - if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) return principal; - boolean success = session.refreshExpiredToken(false); - if (success && session.isActive()) { - refreshCallback(session); - return principal; - } - - logger.debug( - "Cleanup and expire cookie for user {} after failed refresh", principal.getName()); - CookieTokenStore.removeCookie(deployment, facade); - return null; - } -} diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStore.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStore.java deleted file mode 100755 index a932dda6c3..0000000000 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStore.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2016 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.token; - -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.RequestAuthenticator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.util.Assert; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -/** - * Simple Spring {@link SecurityContext security context} aware {@link AdapterTokenStore adapter token store}. - * - * @author Scott Rossillo - * @version $Revision: 1 $ - */ -public class SpringSecurityTokenStore implements AdapterTokenStore { - - private final Logger logger = LoggerFactory.getLogger(SpringSecurityTokenStore.class); - - private final KeycloakDeployment deployment; - private final HttpServletRequest request; - - public SpringSecurityTokenStore(KeycloakDeployment deployment, HttpServletRequest request) { - Assert.notNull(deployment, "KeycloakDeployment is required"); - Assert.notNull(request, "HttpServletRequest is required"); - this.deployment = deployment; - this.request = request; - } - - @Override - public void checkCurrentToken() { - // no-op - } - - @Override - public boolean isCached(RequestAuthenticator authenticator) { - - logger.debug("Checking if {} is cached", authenticator); - SecurityContext context = SecurityContextHolder.getContext(); - KeycloakAuthenticationToken token; - KeycloakSecurityContext keycloakSecurityContext; - - if (context == null || context.getAuthentication() == null) { - return false; - } - - if (!KeycloakAuthenticationToken.class.isAssignableFrom(context.getAuthentication().getClass())) { - logger.warn("Expected a KeycloakAuthenticationToken, but found {}", context.getAuthentication()); - return false; - } - - logger.debug("Remote logged in already. Establishing state from security context."); - token = (KeycloakAuthenticationToken) context.getAuthentication(); - keycloakSecurityContext = token.getAccount().getKeycloakSecurityContext(); - - if (!deployment.getRealm().equals(keycloakSecurityContext.getRealm())) { - logger.debug("Account from security context is from a different realm than for the request."); - logout(); - return false; - } - - if (keycloakSecurityContext.getToken().isExpired()) { - logger.warn("Security token expired ... not returning from cache"); - return false; - } - - request.setAttribute(KeycloakSecurityContext.class.getName(), keycloakSecurityContext); - - return true; - } - - @Override - public void saveAccountInfo(OidcKeycloakAccount account) { - - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - - if (authentication != null) { - throw new IllegalStateException(String.format("Went to save Keycloak account %s, but already have %s", account, authentication)); - } - - logger.debug("Saving account info {}", account); - SecurityContext context = SecurityContextHolder.createEmptyContext(); - context.setAuthentication(new KeycloakAuthenticationToken(account, true)); - SecurityContextHolder.setContext(context); - } - - @Override - public void logout() { - - logger.debug("Handling logout request"); - HttpSession session = request.getSession(false); - - if (session != null) { - session.setAttribute(KeycloakSecurityContext.class.getName(), null); - session.invalidate(); - } - - SecurityContextHolder.clearContext(); - } - - @Override - public void refreshCallback(RefreshableKeycloakSecurityContext securityContext) { - // no-op - } - - @Override - public void saveRequest() { - // no-op, Spring Security will handle this - } - - @Override - public boolean restoreRequest() { - // no-op, Spring Security will handle this - return false; - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBeanTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBeanTest.java deleted file mode 100644 index 3546b5b05d..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/AdapterDeploymentContextFactoryBeanTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016 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; - -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 java.io.FileNotFoundException; - -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/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/HttpHeaderInspectingApiRequestMatcherTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/HttpHeaderInspectingApiRequestMatcherTest.java deleted file mode 100644 index d050eb555a..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/HttpHeaderInspectingApiRequestMatcherTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import org.apache.http.HttpHeaders; -import org.junit.Before; -import org.junit.Test; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.security.web.util.matcher.RequestMatcher; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * HTTP header inspecting API request matcher tests. - */ -public class HttpHeaderInspectingApiRequestMatcherTest { - - private RequestMatcher apiRequestMatcher = new HttpHeaderInspectingApiRequestMatcher(); - private MockHttpServletRequest request; - - @Before - public void setUp() throws Exception { - request = new MockHttpServletRequest(); - } - - @Test - public void testMatchesBrowserRequest() throws Exception { - request.addHeader(HttpHeaders.ACCEPT, "application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); - assertFalse(apiRequestMatcher.matches(request)); - } - - @Test - public void testMatchesRequestedWith() throws Exception { - request.addHeader( - HttpHeaderInspectingApiRequestMatcher.X_REQUESTED_WITH_HEADER, - HttpHeaderInspectingApiRequestMatcher.X_REQUESTED_WITH_HEADER_AJAX_VALUE); - - assertTrue(apiRequestMatcher.matches(request)); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationEntryPointTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationEntryPointTest.java deleted file mode 100644 index 76c1f67701..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationEntryPointTest.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.apache.http.HttpHeaders; -import org.junit.Before; -import org.junit.Test; - -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.spi.HttpFacade; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.context.ApplicationContext; -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.web.util.matcher.RequestMatcher; - -/** - * Keycloak authentication entry point tests. - */ -public class KeycloakAuthenticationEntryPointTest { - - private KeycloakAuthenticationEntryPoint authenticationEntryPoint; - private MockHttpServletRequest request; - private MockHttpServletResponse response; - @Mock - private ApplicationContext applicationContext; - - @Mock - private AdapterDeploymentContext adapterDeploymentContext; - - @Mock - private KeycloakDeployment keycloakDeployment; - - @Mock - private RequestMatcher requestMatcher; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - authenticationEntryPoint = new KeycloakAuthenticationEntryPoint(adapterDeploymentContext); - request = new MockHttpServletRequest(); - response = new MockHttpServletResponse(); - when(applicationContext.getBean(eq(AdapterDeploymentContext.class))).thenReturn(adapterDeploymentContext); - when(adapterDeploymentContext.resolveDeployment(any(HttpFacade.class))).thenReturn(keycloakDeployment); - when(keycloakDeployment.isBearerOnly()).thenReturn(Boolean.FALSE); - } - - @Test - public void testCommenceWithRedirect() throws Exception { - configureBrowserRequest(); - authenticationEntryPoint.commence(request, response, null); - assertEquals(HttpStatus.FOUND.value(), response.getStatus()); - assertEquals(KeycloakAuthenticationEntryPoint.DEFAULT_LOGIN_URI, response.getHeader("Location")); - } - - @Test - public void testCommenceWithRedirectAndQueryParameters() throws Exception { - configureBrowserRequest(); - request.setQueryString("prompt=login"); - authenticationEntryPoint.commence(request, response, null); - assertEquals(HttpStatus.FOUND.value(), response.getStatus()); - assertNotEquals(KeycloakAuthenticationEntryPoint.DEFAULT_LOGIN_URI, response.getHeader("Location")); - assertThat(response.getHeader("Location"), containsString(KeycloakAuthenticationEntryPoint.DEFAULT_LOGIN_URI)); - assertThat(response.getHeader("Location"), containsString("prompt=login")); - } - - @Test - public void testCommenceWithRedirectNotRootContext() throws Exception { - configureBrowserRequest(); - String contextPath = "/foo"; - request.setContextPath(contextPath); - authenticationEntryPoint.commence(request, response, null); - assertEquals(HttpStatus.FOUND.value(), response.getStatus()); - assertEquals(contextPath + KeycloakAuthenticationEntryPoint.DEFAULT_LOGIN_URI, response.getHeader("Location")); - } - - @Test - public void testCommenceWithUnauthorizedWithAccept() throws Exception { - request.addHeader(HttpHeaders.ACCEPT, "application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); - authenticationEntryPoint.commence(request, response, null); - assertEquals(HttpStatus.FOUND.value(), response.getStatus()); - assertNull(response.getHeader(HttpHeaders.WWW_AUTHENTICATE)); - } - - @Test - public void testSetLoginUri() throws Exception { - configureBrowserRequest(); - final String logoutUri = "/foo"; - authenticationEntryPoint.setLoginUri(logoutUri); - authenticationEntryPoint.commence(request, response, null); - assertEquals(HttpStatus.FOUND.value(), response.getStatus()); - assertEquals(logoutUri, response.getHeader("Location")); - } - - @Test - public void testCommenceWithCustomRequestMatcher() throws Exception { - new KeycloakAuthenticationEntryPoint(adapterDeploymentContext, requestMatcher) - .commence(request, response, null); - - verify(requestMatcher).matches(request); - } - - private void configureBrowserRequest() { - request.addHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProviderTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProviderTest.java deleted file mode 100644 index 9515b4b8ba..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProviderTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import org.junit.Before; -import org.junit.Test; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.spi.KeycloakAccount; -import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.mockito.internal.util.collections.Sets; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; - -import java.security.Principal; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; - -/** - * Keycloak authentication provider tests. - */ -public class KeycloakAuthenticationProviderTest { - private KeycloakAuthenticationProvider provider = new KeycloakAuthenticationProvider(); - private KeycloakAuthenticationToken token; - private KeycloakAuthenticationToken interactiveToken; - private Set roles = Sets.newSet("user", "admin"); - - @Before - public void setUp() throws Exception { - Principal principal = mock(Principal.class); - RefreshableKeycloakSecurityContext securityContext = mock(RefreshableKeycloakSecurityContext.class); - KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, securityContext); - - token = new KeycloakAuthenticationToken(account, false); - interactiveToken = new KeycloakAuthenticationToken(account, true); - } - - @Test - public void testAuthenticate() throws Exception { - assertAuthenticationResult(provider.authenticate(token)); - } - - @Test - public void testAuthenticateInteractive() throws Exception { - assertAuthenticationResult(provider.authenticate(interactiveToken)); - } - - @Test - public void testSupports() throws Exception { - assertTrue(provider.supports(KeycloakAuthenticationToken.class)); - assertFalse(provider.supports(PreAuthenticatedAuthenticationToken.class)); - } - - @Test - public void testGrantedAuthoritiesMapper() throws Exception { - SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper(); - grantedAuthorityMapper.setPrefix("ROLE_"); - grantedAuthorityMapper.setConvertToUpperCase(true); - provider.setGrantedAuthoritiesMapper(grantedAuthorityMapper); - - Authentication result = provider.authenticate(token); - assertEquals(Sets.newSet("ROLE_USER", "ROLE_ADMIN"), - AuthorityUtils.authorityListToSet(result.getAuthorities())); - } - - private void assertAuthenticationResult(Authentication result) { - assertNotNull(result); - assertEquals(roles, AuthorityUtils.authorityListToSet(result.getAuthorities())); - assertTrue(result.isAuthenticated()); - assertNotNull(result.getPrincipal()); - assertNotNull(result.getCredentials()); - assertNotNull(result.getDetails()); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java deleted file mode 100755 index 12865de1a8..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2016 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.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.spi.HttpFacade; -import org.keycloak.adapters.springsecurity.account.KeycloakRole; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.authentication.AnonymousAuthenticationToken; -import org.springframework.security.authentication.RememberMeAuthenticationToken; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; - -import java.util.Collection; -import java.util.Collections; -import java.util.UUID; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -/** - * Keycloak logout handler tests. - */ -public class KeycloakLogoutHandlerTest { - - private KeycloakAuthenticationToken keycloakAuthenticationToken; - private KeycloakLogoutHandler keycloakLogoutHandler; - - private MockHttpServletRequest request; - private MockHttpServletResponse response; - - @Mock - private AdapterDeploymentContext adapterDeploymentContext; - - @Mock - private OidcKeycloakAccount keycloakAccount; - - @Mock - private KeycloakDeployment keycloakDeployment; - - @Mock - private RefreshableKeycloakSecurityContext session; - - private Collection authorities = Collections.singleton(new KeycloakRole(UUID.randomUUID().toString())); - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - keycloakAuthenticationToken = mock(KeycloakAuthenticationToken.class); - keycloakLogoutHandler = new KeycloakLogoutHandler(adapterDeploymentContext); - request = new MockHttpServletRequest(); - response = new MockHttpServletResponse(); - - when(adapterDeploymentContext.resolveDeployment(any(HttpFacade.class))).thenReturn(keycloakDeployment); - when(keycloakAuthenticationToken.getAccount()).thenReturn(keycloakAccount); - when(keycloakAccount.getKeycloakSecurityContext()).thenReturn(session); - } - - @Test - public void testLogout() throws Exception { - keycloakLogoutHandler.logout(request, response, keycloakAuthenticationToken); - verify(session).logout(eq(keycloakDeployment)); - } - - @Test - public void testLogoutAnonymousAuthentication() throws Exception { - Authentication authentication = new AnonymousAuthenticationToken(UUID.randomUUID().toString(), UUID.randomUUID().toString(), authorities); - keycloakLogoutHandler.logout(request, response, authentication); - verifyZeroInteractions(session); - } - - @Test - public void testLogoutUsernamePasswordAuthentication() throws Exception { - Authentication authentication = new UsernamePasswordAuthenticationToken(UUID.randomUUID().toString(), UUID.randomUUID().toString(), authorities); - keycloakLogoutHandler.logout(request, response, authentication); - verifyZeroInteractions(session); - } - - @Test - public void testLogoutRememberMeAuthentication() throws Exception { - Authentication authentication = new RememberMeAuthenticationToken(UUID.randomUUID().toString(), UUID.randomUUID().toString(), authorities); - keycloakLogoutHandler.logout(request, response, authentication); - verifyZeroInteractions(session); - } - - @Test - public void testLogoutNullAuthentication() throws Exception { - keycloakLogoutHandler.logout(request, response, null); - verifyZeroInteractions(session); - } - - @Test - public void testHandleSingleSignOut() throws Exception { - keycloakLogoutHandler.handleSingleSignOut(request, response, keycloakAuthenticationToken); - verify(session).logout(eq(keycloakDeployment)); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java deleted file mode 100755 index 373a8dd41b..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2016 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.authentication; - -import org.junit.Before; -import org.junit.Test; -import org.keycloak.KeycloakPrincipal; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.AdapterTokenStore; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.OAuthRequestAuthenticator; -import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.keycloak.representations.AccessToken; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.internal.util.collections.Sets; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.core.context.SecurityContextHolder; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Spring Security request authenticator tests. - */ -public class SpringSecurityRequestAuthenticatorTest { - - private SpringSecurityRequestAuthenticator authenticator; - - private MockHttpServletRequest request; - private MockHttpServletResponse response; - - @Mock - private KeycloakDeployment deployment; - - @Mock - private AdapterTokenStore tokenStore; - - @Mock - private KeycloakPrincipal principal; - - @Mock - private AccessToken accessToken; - - @Mock - private AccessToken.Access access; - - @Mock - private RefreshableKeycloakSecurityContext refreshableKeycloakSecurityContext; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - request = spy(new MockHttpServletRequest()); - response = new MockHttpServletResponse(); - HttpFacade facade = new SimpleHttpFacade(request, response); - - authenticator = new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, 443); - - // mocks - when(principal.getKeycloakSecurityContext()).thenReturn(refreshableKeycloakSecurityContext); - - when(refreshableKeycloakSecurityContext.getDeployment()).thenReturn(deployment); - when(refreshableKeycloakSecurityContext.getToken()).thenReturn(accessToken); - - when(accessToken.getRealmAccess()).thenReturn(access); - when(access.getRoles()).thenReturn(Sets.newSet("user", "admin")); - - when(deployment.isUseResourceRoleMappings()).thenReturn(false); - } - - @Test - public void testCreateOAuthAuthenticator() throws Exception { - OAuthRequestAuthenticator oathAuthenticator = authenticator.createOAuthAuthenticator(); - assertNotNull(oathAuthenticator); - } - - @Test - public void testCompleteOAuthAuthentication() throws Exception { - authenticator.completeOAuthAuthentication(principal); - verify(request).setAttribute(eq(KeycloakSecurityContext.class.getName()), eq(refreshableKeycloakSecurityContext)); - verify(tokenStore).saveAccountInfo(any(OidcKeycloakAccount.class)); // FIXME: should verify account - } - - @Test - public void testCompleteBearerAuthentication() throws Exception { - authenticator.completeBearerAuthentication(principal, "foo"); - verify(request).setAttribute(eq(KeycloakSecurityContext.class.getName()), eq(refreshableKeycloakSecurityContext)); - assertNotNull(SecurityContextHolder.getContext().getAuthentication()); - assertTrue(KeycloakAuthenticationToken.class.isAssignableFrom(SecurityContextHolder.getContext().getAuthentication().getClass())); - } - - @Test - public void testGetHttpSessionIdTrue() throws Exception { - String sessionId = authenticator.changeHttpSessionId(true); - assertNotNull(sessionId); - } - - @Test - public void testGetHttpSessionIdFalse() throws Exception { - String sessionId = authenticator.changeHttpSessionId(false); - assertNull(sessionId); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactoryTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactoryTest.java deleted file mode 100755 index bfd3bd022c..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactoryTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2016 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.client; - -import org.apache.http.client.methods.HttpUriRequest; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.springsecurity.account.KeycloakRole; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.Spy; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; - -import java.util.Collections; -import java.util.UUID; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Keycloak client request factory tests. - */ -public class KeycloakClientRequestFactoryTest { - - @Spy - private KeycloakClientRequestFactory factory; - - @Mock - private OidcKeycloakAccount account; - - @Mock - private KeycloakAuthenticationToken keycloakAuthenticationToken; - - @Mock - private KeycloakSecurityContext keycloakSecurityContext; - - @Mock - private HttpUriRequest request; - - private String bearerTokenString; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - bearerTokenString = UUID.randomUUID().toString(); - - SecurityContextHolder.getContext().setAuthentication(keycloakAuthenticationToken); - when(keycloakAuthenticationToken.getAccount()).thenReturn(account); - when(account.getKeycloakSecurityContext()).thenReturn(keycloakSecurityContext); - when(keycloakSecurityContext.getTokenString()).thenReturn(bearerTokenString); - } - - @Test - public void testPostProcessHttpRequest() throws Exception { - factory.postProcessHttpRequest(request); - verify(factory).getKeycloakSecurityContext(); - verify(request).setHeader(eq(KeycloakClientRequestFactory.AUTHORIZATION_HEADER), eq("Bearer " + bearerTokenString)); - } - - @Test - public void testGetKeycloakSecurityContext() throws Exception { - KeycloakSecurityContext context = factory.getKeycloakSecurityContext(); - assertNotNull(context); - assertEquals(keycloakSecurityContext, context); - } - - @Test(expected = IllegalStateException.class) - public void testGetKeycloakSecurityContextInvalidAuthentication() throws Exception { - SecurityContextHolder.getContext().setAuthentication( - new PreAuthenticatedAuthenticationToken("foo", "bar", Collections.singleton(new KeycloakRole("baz")))); - factory.getKeycloakSecurityContext(); - } - - @Test(expected = IllegalStateException.class) - public void testGetKeycloakSecurityContextNullAuthentication() throws Exception { - SecurityContextHolder.clearContext(); - factory.getKeycloakSecurityContext(); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacadeTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacadeTest.java deleted file mode 100644 index 451fdc8744..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacadeTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.keycloak.adapters.springsecurity.facade; - -import org.junit.Before; -import org.junit.Test; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.spi.KeycloakAccount; -import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.mockito.internal.util.collections.Sets; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; - -import java.security.Principal; -import java.util.Set; - -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.mock; - -public class SimpleHttpFacadeTest { - - @Before - public void setup() { - SecurityContext springSecurityContext = SecurityContextHolder.createEmptyContext(); - SecurityContextHolder.setContext(springSecurityContext); - Set roles = Sets.newSet("user"); - Principal principal = mock(Principal.class); - RefreshableKeycloakSecurityContext keycloakSecurityContext = mock(RefreshableKeycloakSecurityContext.class); - KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, keycloakSecurityContext); - KeycloakAuthenticationToken token = new KeycloakAuthenticationToken(account, false); - springSecurityContext.setAuthentication(token); - } - - @Test - public void shouldRetrieveKeycloakSecurityContext() { - SimpleHttpFacade facade = new SimpleHttpFacade(new MockHttpServletRequest(), new MockHttpServletResponse()); - - assertNotNull(facade.getSecurityContext()); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequestTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequestTest.java deleted file mode 100644 index cb259ce5f2..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequestTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2016 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.facade; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.web.bind.annotation.RequestMethod; - -import javax.servlet.http.Cookie; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * Wrapped HTTP servlet request tests. - */ -public class WrappedHttpServletRequestTest { - - private static final String COOKIE_NAME = "oreo"; - private static final String HEADER_MULTI_VALUE = "Multi"; - private static final String HEADER_SINGLE_VALUE = "Single"; - private static final String REQUEST_METHOD = RequestMethod.GET.name(); - private static final String REQUEST_URI = "/foo/bar"; - private static final String QUERY_PARM_1 = "code"; - private static final String QUERY_PARM_2 = "code2"; - - private WrappedHttpServletRequest request; - private MockHttpServletRequest mockHttpServletRequest; - - @Before - public void setUp() throws Exception { - mockHttpServletRequest = new MockHttpServletRequest(); - request = new WrappedHttpServletRequest(mockHttpServletRequest); - - mockHttpServletRequest.setMethod(REQUEST_METHOD); - mockHttpServletRequest.setRequestURI(REQUEST_URI); - - mockHttpServletRequest.setSecure(true); - mockHttpServletRequest.setScheme("https"); - - mockHttpServletRequest.addHeader(HEADER_SINGLE_VALUE, "baz"); - mockHttpServletRequest.addHeader(HEADER_MULTI_VALUE, "foo"); - mockHttpServletRequest.addHeader(HEADER_MULTI_VALUE, "bar"); - - mockHttpServletRequest.addParameter(QUERY_PARM_1, "java"); - mockHttpServletRequest.addParameter(QUERY_PARM_2, "groovy"); - mockHttpServletRequest.setQueryString(String.format("%s=%s&%s=%s", QUERY_PARM_1, "java", QUERY_PARM_2, "groovy")); - mockHttpServletRequest.setCookies(new Cookie(COOKIE_NAME, "yum")); - - mockHttpServletRequest.setContent("All work and no play makes Jack a dull boy".getBytes()); - } - - @Test - public void testGetMethod() throws Exception { - assertNotNull(request.getMethod()); - assertEquals(REQUEST_METHOD, request.getMethod()); - } - - @Test - public void testGetURI() throws Exception { - assertEquals("https://localhost:80" + REQUEST_URI + "?code=java&code2=groovy" , request.getURI()); - } - - @Test - public void testIsSecure() throws Exception { - assertTrue(request.isSecure()); - } - - @Test - public void testGetQueryParamValue() throws Exception { - assertNotNull(request.getQueryParamValue(QUERY_PARM_1)); - assertNotNull(request.getQueryParamValue(QUERY_PARM_2)); - } - - @Test - public void testGetCookie() throws Exception { - assertNotNull(request.getCookie(COOKIE_NAME)); - } - - @Test - public void testGetCookieCookiesNull() throws Exception - { - mockHttpServletRequest.setCookies(null); - request.getCookie(COOKIE_NAME); - } - - @Test - public void testGetHeader() throws Exception { - String header = request.getHeader(HEADER_SINGLE_VALUE); - assertNotNull(header); - assertEquals("baz", header); - } - - @Test - public void testGetHeaders() throws Exception { - List headers = request.getHeaders(HEADER_MULTI_VALUE); - assertNotNull(headers); - assertEquals(2, headers.size()); - assertTrue(headers.contains("foo")); - assertTrue(headers.contains("bar")); - } - - @Test - public void testGetInputStream() throws Exception { - assertNotNull(request.getInputStream()); - } - - @Test - public void testGetRemoteAddr() throws Exception { - assertNotNull(request.getRemoteAddr()); - } -} \ No newline at end of file diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponseTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponseTest.java deleted file mode 100644 index 6349fbb840..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponseTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2016 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.facade; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockHttpServletResponse; - -import javax.servlet.http.Cookie; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class WrappedHttpServletResponseTest { - - private static final String COOKIE_DOMAIN = ".keycloak.org"; - private static final String COOKIE_NAME = "foo"; - private static final String COOKIE_PATH = "/bar"; - private static final String COOKIE_VALUE = "onegreatcookie"; - private static final String HEADER = "Test"; - - private WrappedHttpServletResponse response; - private MockHttpServletResponse mockResponse; - - @Before - public void setUp() throws Exception { - mockResponse = spy(new MockHttpServletResponse()); - response = new WrappedHttpServletResponse(mockResponse); - } - - @Test - public void testResetCookie() throws Exception { - response.resetCookie(COOKIE_NAME, COOKIE_PATH); - verify(mockResponse).addCookie(any(Cookie.class)); - assertEquals(COOKIE_NAME, mockResponse.getCookie(COOKIE_NAME).getName()); - assertEquals(COOKIE_PATH, mockResponse.getCookie(COOKIE_NAME).getPath()); - assertEquals(0, mockResponse.getCookie(COOKIE_NAME).getMaxAge()); - assertEquals("", mockResponse.getCookie(COOKIE_NAME).getValue()); - } - - @Test - public void testSetCookie() throws Exception { - int maxAge = 300; - response.setCookie(COOKIE_NAME, COOKIE_VALUE, COOKIE_PATH, COOKIE_DOMAIN, maxAge, false, true); - verify(mockResponse).addCookie(any(Cookie.class)); - assertEquals(COOKIE_NAME, mockResponse.getCookie(COOKIE_NAME).getName()); - assertEquals(COOKIE_PATH, mockResponse.getCookie(COOKIE_NAME).getPath()); - assertEquals(COOKIE_DOMAIN, mockResponse.getCookie(COOKIE_NAME).getDomain()); - assertEquals(maxAge, mockResponse.getCookie(COOKIE_NAME).getMaxAge()); - assertEquals(COOKIE_VALUE, mockResponse.getCookie(COOKIE_NAME).getValue()); - assertEquals(true, mockResponse.getCookie(COOKIE_NAME).isHttpOnly()); - } - - @Test - public void testSetStatus() throws Exception { - int status = HttpStatus.OK.value(); - response.setStatus(status); - verify(mockResponse).setStatus(eq(status)); - assertEquals(status, mockResponse.getStatus()); - } - - @Test - public void testAddHeader() throws Exception { - String headerValue = "foo"; - response.addHeader(HEADER, headerValue); - verify(mockResponse).addHeader(eq(HEADER), eq(headerValue)); - assertTrue(mockResponse.containsHeader(HEADER)); - } - - @Test - public void testSetHeader() throws Exception { - String headerValue = "foo"; - response.setHeader(HEADER, headerValue); - verify(mockResponse).setHeader(eq(HEADER), eq(headerValue)); - assertTrue(mockResponse.containsHeader(HEADER)); - } - - @Test - public void testGetOutputStream() throws Exception { - assertNotNull(response.getOutputStream()); - verify(mockResponse).getOutputStream(); - } - - @Test - public void testSendError() throws Exception { - int status = HttpStatus.UNAUTHORIZED.value(); - String reason = HttpStatus.UNAUTHORIZED.getReasonPhrase(); - - response.sendError(status, reason); - verify(mockResponse).sendError(eq(status), eq(reason)); - assertEquals(status, mockResponse.getStatus()); - assertEquals(reason, mockResponse.getErrorMessage()); - } - - @Test - @Ignore - public void testEnd() throws Exception { - // TODO: what is an ended response, one that's committed? - } -} \ No newline at end of file diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java deleted file mode 100755 index c0a69c1268..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2016 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.filter; - -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.spi.HttpFacade; -import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException; -import org.keycloak.adapters.springsecurity.account.KeycloakRole; -import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint; -import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationFailureHandler; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.keycloak.common.enums.SslRequired; -import org.keycloak.common.util.KeycloakUriBuilder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.context.ApplicationContext; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; - -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.startsWith; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Keycloak authentication process filter test cases. - */ -public class KeycloakAuthenticationProcessingFilterTest { - - private KeycloakAuthenticationProcessingFilter filter; - - @Mock - private AuthenticationManager authenticationManager; - - @Mock - private AdapterDeploymentContext adapterDeploymentContext; - - @Mock - private FilterChain chain; - - private MockHttpServletRequest request; - - @Mock - private HttpServletResponse response; - - @Mock - private ApplicationContext applicationContext; - - @Mock - private AuthenticationSuccessHandler successHandler; - - @Mock - private AuthenticationFailureHandler failureHandler; - - private KeycloakAuthenticationFailureHandler keycloakFailureHandler; - - @Mock - private OidcKeycloakAccount keycloakAccount; - - @Mock - private KeycloakDeployment keycloakDeployment; - - @Mock - private KeycloakSecurityContext keycloakSecurityContext; - - private final List authorities = Collections.singletonList(new KeycloakRole("ROLE_USER")); - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - request = spy(new MockHttpServletRequest()); - request.setRequestURI("http://host"); - filter = new KeycloakAuthenticationProcessingFilter(authenticationManager); - keycloakFailureHandler = new KeycloakAuthenticationFailureHandler(); - - filter.setApplicationContext(applicationContext); - filter.setAuthenticationSuccessHandler(successHandler); - filter.setAuthenticationFailureHandler(failureHandler); - - 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)); - - - filter.afterPropertiesSet(); - } - - @Test - public void testAttemptAuthenticationExpectRedirect() throws Exception { - when(keycloakDeployment.getAuthUrl()).thenReturn(KeycloakUriBuilder.fromUri("http://localhost:8080/auth")); - when(keycloakDeployment.getResourceName()).thenReturn("resource-name"); - when(keycloakDeployment.getStateCookieName()).thenReturn("kc-cookie"); - when(keycloakDeployment.getSslRequired()).thenReturn(SslRequired.NONE); - when(keycloakDeployment.isBearerOnly()).thenReturn(Boolean.FALSE); - - filter.attemptAuthentication(request, response); - verify(response).setStatus(302); - verify(response).setHeader(eq("Location"), startsWith("http://localhost:8080/auth")); - } - - @Test(expected = KeycloakAuthenticationException.class) - public void testAttemptAuthenticationWithInvalidToken() throws Exception { - request.addHeader("Authorization", "Bearer xxx"); - filter.attemptAuthentication(request, response); - } - - @Test(expected = KeycloakAuthenticationException.class) - public void testAttemptAuthenticationWithInvalidTokenBearerOnly() throws Exception { - when(keycloakDeployment.isBearerOnly()).thenReturn(Boolean.TRUE); - request.addHeader("Authorization", "Bearer xxx"); - filter.attemptAuthentication(request, response); - } - - @Test - public void testSuccessfulAuthenticationInteractive() throws Exception { - request.setRequestURI("http://host" + KeycloakAuthenticationEntryPoint.DEFAULT_LOGIN_URI + "?query"); - Authentication authentication = new KeycloakAuthenticationToken(keycloakAccount, true, authorities); - filter.successfulAuthentication(request, response, chain, authentication); - - verify(successHandler).onAuthenticationSuccess(eq(request), eq(response), eq(authentication)); - verify(chain, never()).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class)); - } - - @Test - public void testSuccessfulAuthenticationBearer() throws Exception { - Authentication authentication = new KeycloakAuthenticationToken(keycloakAccount, false, authorities); - this.setBearerAuthHeader(request); - filter.successfulAuthentication(request, response, chain, authentication); - - verify(chain).doFilter(eq(request), eq(response)); - verify(successHandler, never()).onAuthenticationSuccess(any(HttpServletRequest.class), any(HttpServletResponse.class), - any(Authentication.class)); - } - - @Test - public void testSuccessfulAuthenticationBasicAuth() throws Exception { - Authentication authentication = new KeycloakAuthenticationToken(keycloakAccount, false, authorities); - this.setBasicAuthHeader(request); - filter.successfulAuthentication(request, response, chain, authentication); - - verify(chain).doFilter(eq(request), eq(response)); - verify(successHandler, never()).onAuthenticationSuccess(any(HttpServletRequest.class), any(HttpServletResponse.class), - any(Authentication.class)); - } - - @Test - public void testUnsuccessfulAuthenticationInteractive() throws Exception { - AuthenticationException exception = new BadCredentialsException("OOPS"); - filter.unsuccessfulAuthentication(request, response, exception); - verify(failureHandler).onAuthenticationFailure(eq(request), eq(response), eq(exception)); - } - - @Test - public void testUnsuccessfulAuthenticatioBearer() throws Exception { - AuthenticationException exception = new BadCredentialsException("OOPS"); - this.setBearerAuthHeader(request); - filter.unsuccessfulAuthentication(request, response, exception); - verify(failureHandler).onAuthenticationFailure(any(HttpServletRequest.class), any(HttpServletResponse.class), - any(AuthenticationException.class)); - } - - @Test - public void testUnsuccessfulAuthenticatioBasicAuth() throws Exception { - AuthenticationException exception = new BadCredentialsException("OOPS"); - this.setBasicAuthHeader(request); - filter.unsuccessfulAuthentication(request, response, exception); - verify(failureHandler).onAuthenticationFailure(any(HttpServletRequest.class), any(HttpServletResponse.class), - any(AuthenticationException.class)); - } - - @Test - public void testDefaultFailureHanlder() throws Exception { - AuthenticationException exception = new BadCredentialsException("OOPS"); - filter.setAuthenticationFailureHandler(keycloakFailureHandler); - filter.unsuccessfulAuthentication(request, response, exception); - - verify(response).sendError(eq(HttpServletResponse.SC_UNAUTHORIZED), any(String.class)); - } - - @Test(expected = UnsupportedOperationException.class) - public void testSetAllowSessionCreation() throws Exception { - filter.setAllowSessionCreation(true); - } - - @Test(expected = UnsupportedOperationException.class) - public void testSetContinueChainBeforeSuccessfulAuthentication() throws Exception { - filter.setContinueChainBeforeSuccessfulAuthentication(true); - } - - private void setBearerAuthHeader(MockHttpServletRequest request) { - setAuthorizationHeader(request, "Bearer"); - } - - private void setBasicAuthHeader(MockHttpServletRequest request) { - setAuthorizationHeader(request, "Basic"); - } - - private void setAuthorizationHeader(MockHttpServletRequest request, String scheme) { - request.addHeader(KeycloakAuthenticationProcessingFilter.AUTHORIZATION_HEADER, scheme + " " + UUID.randomUUID().toString()); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakCsrfRequestMatcherTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakCsrfRequestMatcherTest.java deleted file mode 100644 index 15a15ad710..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakCsrfRequestMatcherTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2016 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.filter; - -import org.junit.Before; -import org.junit.Test; -import org.keycloak.constants.AdapterConstants; -import org.springframework.http.HttpMethod; -import org.springframework.mock.web.MockHttpServletRequest; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Keycloak CSRF request matcher tests. - */ -public class KeycloakCsrfRequestMatcherTest { - - private static final String ROOT_CONTEXT_PATH = ""; - private static final String SUB_CONTEXT_PATH = "/foo"; - - private KeycloakCsrfRequestMatcher matcher = new KeycloakCsrfRequestMatcher(); - - private MockHttpServletRequest request; - - @Before - public void setUp() throws Exception { - request = new MockHttpServletRequest(); - } - - @Test - public void testMatchesMethodGet() throws Exception { - request.setMethod(HttpMethod.GET.name()); - assertFalse(matcher.matches(request)); - } - - @Test - public void testMatchesMethodPost() throws Exception { - prepareRequest(HttpMethod.POST, ROOT_CONTEXT_PATH, "some/random/uri"); - assertTrue(matcher.matches(request)); - - prepareRequest(HttpMethod.POST, SUB_CONTEXT_PATH, "some/random/uri"); - assertTrue(matcher.matches(request)); - } - - @Test - public void testMatchesKeycloakLogout() throws Exception { - - prepareRequest(HttpMethod.POST, ROOT_CONTEXT_PATH, AdapterConstants.K_LOGOUT); - assertFalse(matcher.matches(request)); - - prepareRequest(HttpMethod.POST, SUB_CONTEXT_PATH, AdapterConstants.K_LOGOUT); - assertFalse(matcher.matches(request)); - } - - @Test - public void testMatchesKeycloakPushNotBefore() throws Exception { - - prepareRequest(HttpMethod.POST, ROOT_CONTEXT_PATH, AdapterConstants.K_PUSH_NOT_BEFORE); - assertFalse(matcher.matches(request)); - - prepareRequest(HttpMethod.POST, SUB_CONTEXT_PATH, AdapterConstants.K_PUSH_NOT_BEFORE); - assertFalse(matcher.matches(request)); - } - - @Test - public void testMatchesKeycloakQueryBearerToken() throws Exception { - - prepareRequest(HttpMethod.POST, ROOT_CONTEXT_PATH, AdapterConstants.K_QUERY_BEARER_TOKEN); - assertFalse(matcher.matches(request)); - - prepareRequest(HttpMethod.POST, SUB_CONTEXT_PATH, AdapterConstants.K_QUERY_BEARER_TOKEN); - assertFalse(matcher.matches(request)); - } - - @Test - public void testMatchesKeycloakTestAvailable() throws Exception { - - prepareRequest(HttpMethod.POST, ROOT_CONTEXT_PATH, AdapterConstants.K_TEST_AVAILABLE); - assertFalse(matcher.matches(request)); - - prepareRequest(HttpMethod.POST, SUB_CONTEXT_PATH, AdapterConstants.K_TEST_AVAILABLE); - assertFalse(matcher.matches(request)); - } - - private void prepareRequest(HttpMethod method, String contextPath, String uri) { - request.setMethod(method.name()); - request.setContextPath(contextPath); - request.setRequestURI(contextPath + "/" + uri); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilterTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilterTest.java deleted file mode 100644 index d23fd8fea6..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilterTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.keycloak.adapters.springsecurity.filter; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.NodesRegistrationManagement; -import org.keycloak.adapters.PreAuthActionsHandler; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.adapters.spi.UserSessionManagement; -import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.PreAuthActionsHandlerFactory; -import org.mockito.Mock; -import org.springframework.context.ApplicationContext; - -public class KeycloakPreAuthActionsFilterTest { - - private KeycloakPreAuthActionsFilter filter; - - @Mock - private NodesRegistrationManagement nodesRegistrationManagement; - @Mock - private ApplicationContext applicationContext; - @Mock - private AdapterDeploymentContext deploymentContext; - @Mock - private PreAuthActionsHandlerFactory preAuthActionsHandlerFactory; - @Mock - private UserSessionManagement userSessionManagement; - @Mock - private PreAuthActionsHandler preAuthActionsHandler; - @Mock - private KeycloakDeployment deployment; - - @Mock - private HttpServletRequest request; - @Mock - private HttpServletResponse response; - @Mock - private FilterChain chain; - - @Before - public void setUp() throws Exception { - initMocks(this); - filter = new KeycloakPreAuthActionsFilter(userSessionManagement); - filter.setNodesRegistrationManagement(nodesRegistrationManagement); - filter.setApplicationContext(applicationContext); - filter.setPreAuthActionsHandlerFactory(preAuthActionsHandlerFactory); - when(applicationContext.getBean(AdapterDeploymentContext.class)).thenReturn(deploymentContext); - when(deploymentContext.resolveDeployment(any(HttpFacade.class))).thenReturn(deployment); - when(preAuthActionsHandlerFactory.createPreAuthActionsHandler(any(HttpFacade.class))).thenReturn(preAuthActionsHandler); - when(deployment.isConfigured()).thenReturn(true); - filter.initFilterBean(); - } - - @Test - public void shouldIgnoreChainWhenPreAuthActionHandlerHandled() throws Exception { - when(preAuthActionsHandler.handleRequest()).thenReturn(true); - - filter.doFilter(request, response, chain); - - verifyZeroInteractions(chain); - verify(nodesRegistrationManagement).tryRegister(deployment); - } - - @Test - public void shouldContinueChainWhenPreAuthActionHandlerDidNotHandle() throws Exception { - when(preAuthActionsHandler.handleRequest()).thenReturn(false); - - filter.doFilter(request, response, chain); - - verify(chain).doFilter(request, response);; - verify(nodesRegistrationManagement).tryRegister(deployment); - } - - @After - public void tearDown() { - filter.destroy(); - verify(nodesRegistrationManagement).stop(); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/QueryParamPresenceRequestMatcherTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/QueryParamPresenceRequestMatcherTest.java deleted file mode 100644 index 0e02856df7..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/QueryParamPresenceRequestMatcherTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2017 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.filter; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Collections; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.http.HttpMethod; -import org.springframework.mock.web.MockHttpServletRequest; - -public class QueryParamPresenceRequestMatcherTest { - private static final String ROOT_CONTEXT_PATH = ""; - - private static final String VALID_PARAMETER = "access_token"; - - private QueryParamPresenceRequestMatcher matcher = new QueryParamPresenceRequestMatcher(VALID_PARAMETER); - - private MockHttpServletRequest request; - - @Before - public void setUp() throws Exception { - request = new MockHttpServletRequest(); - } - - @Test - public void testDoesNotMatchWithoutQueryParameter() throws Exception { - prepareRequest(HttpMethod.GET, ROOT_CONTEXT_PATH, "some/random/uri", Collections.EMPTY_MAP); - assertFalse(matcher.matches(request)); - } - - @Test - public void testMatchesWithValidParameter() throws Exception { - prepareRequest(HttpMethod.GET, ROOT_CONTEXT_PATH, "some/random/uri", Collections.singletonMap(VALID_PARAMETER, (Object) "123")); - assertTrue(matcher.matches(request)); - } - - @Test - public void testDoesNotMatchWithInvalidParameter() throws Exception { - prepareRequest(HttpMethod.GET, ROOT_CONTEXT_PATH, "some/random/uri", Collections.singletonMap("some_parameter", (Object) "123")); - assertFalse(matcher.matches(request)); - } - - private void prepareRequest(HttpMethod method, String contextPath, String uri, Map params) { - request.setMethod(method.name()); - request.setContextPath(contextPath); - request.setRequestURI(contextPath + "/" + uri); - request.setParameters(params); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityAdapterTokenStoreFactoryTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityAdapterTokenStoreFactoryTest.java deleted file mode 100755 index 6984cd5fa5..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityAdapterTokenStoreFactoryTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2016 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.token; - -import org.junit.Before; -import org.junit.Test; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.spi.AdapterSessionStore; -import org.keycloak.enums.TokenStore; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; - -/** - * Spring Security adapter token store factory tests. - */ -public class SpringSecurityAdapterTokenStoreFactoryTest { - - private AdapterTokenStoreFactory factory = new SpringSecurityAdapterTokenStoreFactory(); - - @Mock - private KeycloakDeployment deployment; - - @Mock - private HttpServletRequest request; - - @Mock - private HttpServletResponse response; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testCreateAdapterTokenStore() throws Exception { - when(deployment.getTokenStore()).thenReturn(TokenStore.SESSION); - AdapterSessionStore store = factory.createAdapterTokenStore(deployment, request, response); - assertTrue(store instanceof SpringSecurityTokenStore); - } - - @Test - public void testCreateAdapterTokenStoreUsingCookies() throws Exception { - when(deployment.getTokenStore()).thenReturn(TokenStore.COOKIE); - AdapterSessionStore store = factory.createAdapterTokenStore(deployment, request, response); - assertTrue(store instanceof SpringSecurityCookieTokenStore); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateAdapterTokenStoreNullDeployment() throws Exception { - factory.createAdapterTokenStore(null, request, response); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateAdapterTokenStoreNullRequest() throws Exception { - factory.createAdapterTokenStore(deployment, null, response); - } - - @Test - public void testCreateAdapterTokenStoreNullResponse() throws Exception { - when(deployment.getTokenStore()).thenReturn(TokenStore.SESSION); - factory.createAdapterTokenStore(deployment, request, null); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateAdapterTokenStoreNullResponseUsingCookies() throws Exception { - when(deployment.getTokenStore()).thenReturn(TokenStore.COOKIE); - factory.createAdapterTokenStore(deployment, request, null); - } -} diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStoreTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStoreTest.java deleted file mode 100755 index 8b5ebbc40f..0000000000 --- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStoreTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016 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.token; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.OidcKeycloakAccount; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.adapters.RequestAuthenticator; -import org.keycloak.adapters.springsecurity.account.KeycloakRole; -import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; - -import java.security.Principal; -import java.util.Collections; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * Spring Security token store tests. - */ -public class SpringSecurityTokenStoreTest { - - private SpringSecurityTokenStore store; - - @Mock - private KeycloakDeployment deployment; - - @Mock - private Principal principal; - - @Mock - private RequestAuthenticator requestAuthenticator; - - @Mock - private RefreshableKeycloakSecurityContext keycloakSecurityContext; - - private MockHttpServletRequest request; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - request = new MockHttpServletRequest(); - store = new SpringSecurityTokenStore(deployment, request); - } - - @After - public void tearDown() throws Exception { - SecurityContextHolder.clearContext(); - } - - @Test - public void testIsCached() throws Exception { - Authentication authentication = new PreAuthenticatedAuthenticationToken("foo", "bar", Collections.singleton(new KeycloakRole("ROLE_FOO"))); - SecurityContextHolder.getContext().setAuthentication(authentication); - assertFalse(store.isCached(requestAuthenticator)); - } - - @Test - public void testSaveAccountInfo() throws Exception { - OidcKeycloakAccount account = new SimpleKeycloakAccount(principal, Collections.singleton("FOO"), keycloakSecurityContext); - Authentication authentication; - - store.saveAccountInfo(account); - authentication = SecurityContextHolder.getContext().getAuthentication(); - - assertNotNull(authentication); - assertTrue(authentication instanceof KeycloakAuthenticationToken); - } - - @Test(expected = IllegalStateException.class) - public void testSaveAccountInfoInvalidAuthenticationType() throws Exception { - OidcKeycloakAccount account = new SimpleKeycloakAccount(principal, Collections.singleton("FOO"), keycloakSecurityContext); - Authentication authentication = new PreAuthenticatedAuthenticationToken("foo", "bar", Collections.singleton(new KeycloakRole("ROLE_FOO"))); - SecurityContextHolder.getContext().setAuthentication(authentication); - store.saveAccountInfo(account); - } - - @Test - public void testLogout() throws Exception { - MockHttpSession session = (MockHttpSession) request.getSession(true); - assertFalse(session.isInvalid()); - store.logout(); - assertTrue(session.isInvalid()); - } -} diff --git a/adapters/oidc/spring-security/src/test/resources/keycloak.json b/adapters/oidc/spring-security/src/test/resources/keycloak.json deleted file mode 100644 index 61e0f9371d..0000000000 --- a/adapters/oidc/spring-security/src/test/resources/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm": "spring-security", - "realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh65Gqi3BSaVe12JHlqChWm8WscICrj46MVqmRoO9FCmqbxEpCQhE1RLjW+GDyc3YdXW3xqUQ3AZxDkTmN1h6BWkhdxPLzA4EnwgWmGurhyJlUF9Id2tKns0jbC+Z7kIb2LcOiKHKL7mRb3q7EtWubNnrvunv8fx+WeXGaQoGEVQIDAQAB", - "auth-server-url": "http://localhost:8080/auth", - "ssl-required": "external", - "resource": "some-resource", - "credentials": { - "secret": "a9c3501e-20dd-4277-8a7b-351063848446" - } -} diff --git a/docs/documentation/securing_apps/topics/oidc/java/java-adapters.adoc b/docs/documentation/securing_apps/topics/oidc/java/java-adapters.adoc index 103927f277..e417fb3d70 100644 --- a/docs/documentation/securing_apps/topics/oidc/java/java-adapters.adoc +++ b/docs/documentation/securing_apps/topics/oidc/java/java-adapters.adoc @@ -17,10 +17,6 @@ include::java-adapter-config.adoc[] endif::[] include::jboss-adapter.adoc[] -ifeval::[{project_community}==true] -include::spring-security-adapter.adoc[] -endif::[] - ifeval::[{project_community}==true] include::servlet-filter-adapter.adoc[] endif::[] diff --git a/docs/documentation/securing_apps/topics/oidc/java/spring-security-adapter.adoc b/docs/documentation/securing_apps/topics/oidc/java/spring-security-adapter.adoc deleted file mode 100644 index 8b63c06034..0000000000 --- a/docs/documentation/securing_apps/topics/oidc/java/spring-security-adapter.adoc +++ /dev/null @@ -1,297 +0,0 @@ - -[[_spring_security_adapter]] -==== Spring Security adapter - -[WARNING] -==== -This adapter is deprecated and will be removed in a future release of Keycloak. No further enhancements or new features -will be added to this adapter. - -We recommend that you leverage the OAuth2/OpenID Connect support from Spring Security. - -For more details about how to integrate {project_name} with Spring Boot applications, consider looking at the -{quickstartRepo_link}[Keycloak Quickstart GitHub Repository]. -==== - -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. - -Unlike the other Keycloak Adapters, you should not configure your security in web.xml. -However, keycloak.json is still required. -In order for Single Sign Out to work properly you have to define a session listener. - -.The session listener can be defined: -* in web.xml (for pure Spring Security environments): -[source,xml] ----- - - org.springframework.security.web.session.HttpSessionEventPublisher - ----- -* as a Spring bean (in Spring Boot environments using Spring Security adapter) -[source,java] ----- -@Bean -public ServletListenerRegistrationBean httpSessionEventPublisher() { - return new ServletListenerRegistrationBean(new HttpSessionEventPublisher()); -} ----- - - -===== Installing the adapter - -Add Keycloak Spring Security adapter as a dependency to your Maven POM or Gradle build. - - -[source,xml,subs="attributes+"] ----- - - org.keycloak - keycloak-spring-security-adapter - {project_versionMvn} - ----- - -===== Configuring the Spring Security Adapter - -The Keycloak Spring Security adapter takes advantage of Spring Security's flexible security configuration syntax. - -====== Java configuration - -Keycloak provides a KeycloakWebSecurityConfigurerAdapter as a convenient base class for creating a https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/WebSecurityConfigurer.html[WebSecurityConfigurer] instance. -The implementation allows customization by overriding methods. -While its use is not required, it greatly simplifies your security context configuration. - - -[source,java] ----- - - -@KeycloakConfiguration -public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter -{ - /** - * Registers the KeycloakAuthenticationProvider with the authentication manager. - */ - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth.authenticationProvider(keycloakAuthenticationProvider()); - } - - /** - * Defines the session authentication strategy. - */ - @Bean - @Override - protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { - return new RegisterSessionAuthenticationStrategy(buildSessionRegistry()); - } - - @Bean - protected SessionRegistry buildSessionRegistry() { - return new SessionRegistryImpl(); - } - - @Override - protected void configure(HttpSecurity http) throws Exception - { - super.configure(http); - http - .authorizeRequests() - .antMatchers("/customers*").hasRole("USER") - .antMatchers("/admin*").hasRole("ADMIN") - .anyRequest().permitAll(); - } -} ----- - -You must provide a session authentication strategy bean which should be of type `RegisterSessionAuthenticationStrategy` for public or confidential applications and `NullAuthenticatedSessionStrategy` for bearer-only applications. - -Spring Security's `SessionFixationProtectionStrategy` is currently not supported because it changes the session identifier after login via Keycloak. -If the session identifier changes, universal log out will not work because Keycloak is unaware of the new session identifier. - -TIP: The `@KeycloakConfiguration` annotation is a metadata annotation that defines all annotations that are needed to integrate -{project_name} in Spring Security. If you have a complex Spring Security setup you can simply have a look at the annotations of -the `@KeycloakConfiguration` annotation and create your own custom meta annotation or just use specific Spring annotations -for the {project_name} adapter. - -====== XML configuration - -While Spring Security's XML namespace simplifies configuration, customizing the configuration can be a bit verbose. - - -[source,xml] ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----- - -===== 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 <<_multi_tenancy,Multi Tenancy>>. - -===== Naming security roles - -Spring Security, when using role-based authentication, requires that role names start with `ROLE_`. -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`, which allows for case conversion and the addition of a prefix (which defaults to `ROLE_`). -The following code will convert the role names to upper case and, by default, add the `ROLE_` prefix to them: - -[source,java] ----- -@KeycloakConfiguration -public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) { - auth.authenticationProvider(getKeycloakAuthenticationProvider()); - } - - private KeycloakAuthenticationProvider getKeycloakAuthenticationProvider() { - KeycloakAuthenticationProvider authenticationProvider = keycloakAuthenticationProvider(); - SimpleAuthorityMapper mapper = new SimpleAuthorityMapper(); - mapper.setConvertToUpperCase(true); - authenticationProvider.setGrantedAuthoritiesMapper(mapper); - - return authenticationProvider; - } - - ... -} - ----- - -===== Client to Client Support - -To simplify communication between clients, Keycloak provides an extension of Spring's `RestTemplate` that handles bearer token authentication for you. -To enable this feature your security configuration must add the `KeycloakRestTemplate` bean. -Note that it must be scoped as a prototype to function correctly. - -For Java configuration: -[source,java] ----- - - -@Configuration -@EnableWebSecurity -@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) -public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { - - ... - - @Autowired - public KeycloakClientRequestFactory keycloakClientRequestFactory; - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public KeycloakRestTemplate keycloakRestTemplate() { - return new KeycloakRestTemplate(keycloakClientRequestFactory); - } - - ... -} ----- - -For XML configuration: -[source,xml] ----- - - - - - ----- - -Your application code can then use `KeycloakRestTemplate` any time it needs to make a call to another client. -For example: -[source,java] ----- - - - -@Service -public class RemoteProductService implements ProductService { - - @Autowired - private KeycloakRestTemplate template; - - private String endpoint; - - @Override - public List getProducts() { - ResponseEntity response = template.getForEntity(endpoint, String[].class); - return Arrays.asList(response.getBody()); - } -} ----- \ No newline at end of file diff --git a/docs/documentation/securing_apps/topics/overview/getting-started.adoc b/docs/documentation/securing_apps/topics/overview/getting-started.adoc index 888f2bc1a3..2c5cc14cf2 100644 --- a/docs/documentation/securing_apps/topics/overview/getting-started.adoc +++ b/docs/documentation/securing_apps/topics/overview/getting-started.adoc @@ -15,7 +15,6 @@ ifeval::[{project_community}==true] * {quickstartRepo_link}/tree/latest/spring/rest-authz-resource-server[Spring Boot] * <<_jboss_adapter, {project_name} Wildfly Adapter>> (Deprecated) * <<_servlet_filter_adapter,{project_name} Servlet Filter>> (Deprecated) -* <<_spring_security_adapter,{project_name} Spring Security>> (Deprecated) endif::[] ===== JavaScript (client-side)