diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepository.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepository.java index f6b88a29f0..c3894ce94f 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepository.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepository.java @@ -16,9 +16,6 @@ package org.springframework.security.oauth2.client.web; -import java.util.HashMap; -import java.util.Map; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; @@ -46,17 +43,16 @@ public final class HttpSessionOAuth2AuthorizationRequestRepository private final String sessionAttributeName = DEFAULT_AUTHORIZATION_REQUEST_ATTR_NAME; - private boolean allowMultipleAuthorizationRequests; - @Override public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) { Assert.notNull(request, "request cannot be null"); - String stateParameter = this.getStateParameter(request); + String stateParameter = getStateParameter(request); if (stateParameter == null) { return null; } - Map authorizationRequests = this.getAuthorizationRequests(request); - return authorizationRequests.get(stateParameter); + OAuth2AuthorizationRequest authorizationRequest = getAuthorizationRequest(request); + return (authorizationRequest != null && stateParameter.equals(authorizationRequest.getState())) + ? authorizationRequest : null; } @Override @@ -65,43 +61,23 @@ public final class HttpSessionOAuth2AuthorizationRequestRepository Assert.notNull(request, "request cannot be null"); Assert.notNull(response, "response cannot be null"); if (authorizationRequest == null) { - this.removeAuthorizationRequest(request, response); + removeAuthorizationRequest(request, response); return; } String state = authorizationRequest.getState(); Assert.hasText(state, "authorizationRequest.state cannot be empty"); - if (this.allowMultipleAuthorizationRequests) { - Map authorizationRequests = this.getAuthorizationRequests(request); - authorizationRequests.put(state, authorizationRequest); - request.getSession().setAttribute(this.sessionAttributeName, authorizationRequests); - } - else { - request.getSession().setAttribute(this.sessionAttributeName, authorizationRequest); - } + request.getSession().setAttribute(this.sessionAttributeName, authorizationRequest); } @Override public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { - Assert.notNull(request, "request cannot be null"); Assert.notNull(response, "response cannot be null"); - String stateParameter = this.getStateParameter(request); - if (stateParameter == null) { - return null; - } - Map authorizationRequests = this.getAuthorizationRequests(request); - OAuth2AuthorizationRequest originalRequest = authorizationRequests.remove(stateParameter); - if (authorizationRequests.size() == 0) { + OAuth2AuthorizationRequest authorizationRequest = loadAuthorizationRequest(request); + if (authorizationRequest != null) { request.getSession().removeAttribute(this.sessionAttributeName); } - else if (authorizationRequests.size() == 1) { - request.getSession().setAttribute(this.sessionAttributeName, - authorizationRequests.values().iterator().next()); - } - else { - request.getSession().setAttribute(this.sessionAttributeName, authorizationRequests); - } - return originalRequest; + return authorizationRequest; } /** @@ -113,48 +89,9 @@ public final class HttpSessionOAuth2AuthorizationRequestRepository return request.getParameter(OAuth2ParameterNames.STATE); } - /** - * Gets a non-null and mutable map of {@link OAuth2AuthorizationRequest#getState()} to - * an {@link OAuth2AuthorizationRequest} - * @param request - * @return a non-null and mutable map of {@link OAuth2AuthorizationRequest#getState()} - * to an {@link OAuth2AuthorizationRequest}. - */ - private Map getAuthorizationRequests(HttpServletRequest request) { + private OAuth2AuthorizationRequest getAuthorizationRequest(HttpServletRequest request) { HttpSession session = request.getSession(false); - Object sessionAttributeValue = (session != null) ? session.getAttribute(this.sessionAttributeName) : null; - if (sessionAttributeValue == null) { - return new HashMap<>(); - } - else if (sessionAttributeValue instanceof OAuth2AuthorizationRequest) { - OAuth2AuthorizationRequest auth2AuthorizationRequest = (OAuth2AuthorizationRequest) sessionAttributeValue; - Map authorizationRequests = new HashMap<>(1); - authorizationRequests.put(auth2AuthorizationRequest.getState(), auth2AuthorizationRequest); - return authorizationRequests; - } - else if (sessionAttributeValue instanceof Map) { - @SuppressWarnings("unchecked") - Map authorizationRequests = (Map) sessionAttributeValue; - return authorizationRequests; - } - else { - throw new IllegalStateException( - "authorizationRequests is supposed to be a Map or OAuth2AuthorizationRequest but actually is a " - + sessionAttributeValue.getClass()); - } - } - - /** - * Configure if multiple {@link OAuth2AuthorizationRequest}s should be stored per - * session. Default is false (not allow multiple {@link OAuth2AuthorizationRequest} - * per session). - * @param allowMultipleAuthorizationRequests true allows more than one - * {@link OAuth2AuthorizationRequest} to be stored per session. - * @since 5.5 - */ - @Deprecated - public void setAllowMultipleAuthorizationRequests(boolean allowMultipleAuthorizationRequests) { - this.allowMultipleAuthorizationRequests = allowMultipleAuthorizationRequests; + return (session != null) ? (OAuth2AuthorizationRequest) session.getAttribute(this.sessionAttributeName) : null; } } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepository.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepository.java index 47eee77365..3aa9229b08 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepository.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.security.oauth2.client.web.server; -import java.util.HashMap; import java.util.Map; import reactor.core.publisher.Mono; @@ -47,8 +46,6 @@ public final class WebSessionOAuth2ServerAuthorizationRequestRepository private final String sessionAttributeName = DEFAULT_AUTHORIZATION_REQUEST_ATTR_NAME; - private boolean allowMultipleAuthorizationRequests; - @Override public Mono loadAuthorizationRequest(ServerWebExchange exchange) { String state = getStateParameter(exchange); @@ -56,11 +53,10 @@ public final class WebSessionOAuth2ServerAuthorizationRequestRepository return Mono.empty(); } // @formatter:off - return this.getSessionAttributes(exchange) + return getSessionAttributes(exchange) .filter((sessionAttrs) -> sessionAttrs.containsKey(this.sessionAttributeName)) - .map(this::getAuthorizationRequests) - .filter((stateToAuthorizationRequest) -> stateToAuthorizationRequest.containsKey(state)) - .map((stateToAuthorizationRequest) -> stateToAuthorizationRequest.get(state)); + .map(this::getAuthorizationRequest) + .filter((authorizationRequest) -> state.equals(authorizationRequest.getState())); // @formatter:on } @@ -72,15 +68,8 @@ public final class WebSessionOAuth2ServerAuthorizationRequestRepository // @formatter:off return getSessionAttributes(exchange) .doOnNext((sessionAttrs) -> { - if (this.allowMultipleAuthorizationRequests) { - Map authorizationRequests = this.getAuthorizationRequests( - sessionAttrs); - authorizationRequests.put(authorizationRequest.getState(), authorizationRequest); - sessionAttrs.put(this.sessionAttributeName, authorizationRequests); - } - else { - sessionAttrs.put(this.sessionAttributeName, authorizationRequest); - } + Assert.hasText(authorizationRequest.getState(), "authorizationRequest.state cannot be empty"); + sessionAttrs.put(this.sessionAttributeName, authorizationRequest); }) .then(); // @formatter:on @@ -94,20 +83,14 @@ public final class WebSessionOAuth2ServerAuthorizationRequestRepository } // @formatter:off return getSessionAttributes(exchange) + .filter((sessionAttrs) -> sessionAttrs.containsKey(this.sessionAttributeName)) .flatMap((sessionAttrs) -> { - Map authorizationRequests = this.getAuthorizationRequests( - sessionAttrs); - OAuth2AuthorizationRequest originalRequest = authorizationRequests.remove(state); - if (authorizationRequests.isEmpty()) { + OAuth2AuthorizationRequest authorizationRequest = (OAuth2AuthorizationRequest) sessionAttrs.get(this.sessionAttributeName); + if (state.equals(authorizationRequest.getState())) { sessionAttrs.remove(this.sessionAttributeName); + return Mono.just(authorizationRequest); } - else if (authorizationRequests.size() == 1) { - sessionAttrs.put(this.sessionAttributeName, authorizationRequests.values().iterator().next()); - } - else { - sessionAttrs.put(this.sessionAttributeName, authorizationRequests); - } - return Mono.justOrEmpty(originalRequest); + return Mono.empty(); }); // @formatter:on } @@ -126,41 +109,8 @@ public final class WebSessionOAuth2ServerAuthorizationRequestRepository return exchange.getSession().map(WebSession::getAttributes); } - private Map getAuthorizationRequests(Map sessionAttrs) { - Object sessionAttributeValue = sessionAttrs.get(this.sessionAttributeName); - if (sessionAttributeValue == null) { - return new HashMap<>(); - } - else if (sessionAttributeValue instanceof OAuth2AuthorizationRequest) { - OAuth2AuthorizationRequest oauth2AuthorizationRequest = (OAuth2AuthorizationRequest) sessionAttributeValue; - Map authorizationRequests = new HashMap<>(1); - authorizationRequests.put(oauth2AuthorizationRequest.getState(), oauth2AuthorizationRequest); - return authorizationRequests; - } - else if (sessionAttributeValue instanceof Map) { - @SuppressWarnings("unchecked") - Map authorizationRequests = (Map) sessionAttrs - .get(this.sessionAttributeName); - return authorizationRequests; - } - else { - throw new IllegalStateException( - "authorizationRequests is supposed to be a Map or OAuth2AuthorizationRequest but actually is a " - + sessionAttributeValue.getClass()); - } - } - - /** - * Configure if multiple {@link OAuth2AuthorizationRequest}s should be stored per - * session. Default is false (not allow multiple {@link OAuth2AuthorizationRequest} - * per session). - * @param allowMultipleAuthorizationRequests true allows more than one - * {@link OAuth2AuthorizationRequest} to be stored per session. - * @since 5.5 - */ - @Deprecated - public void setAllowMultipleAuthorizationRequests(boolean allowMultipleAuthorizationRequests) { - this.allowMultipleAuthorizationRequests = allowMultipleAuthorizationRequests; + private OAuth2AuthorizationRequest getAuthorizationRequest(Map sessionAttrs) { + return (OAuth2AuthorizationRequest) sessionAttrs.get(this.sessionAttributeName); } } diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryAllowMultipleAuthorizationRequestsTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryAllowMultipleAuthorizationRequestsTests.java deleted file mode 100644 index 2a55a96a3f..0000000000 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryAllowMultipleAuthorizationRequestsTests.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * 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 - * - * https://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.springframework.security.oauth2.client.web; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; -import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HttpSessionOAuth2AuthorizationRequestRepository} when - * {@link HttpSessionOAuth2AuthorizationRequestRepository#setAllowMultipleAuthorizationRequests(boolean)} - * is enabled. - * - * @author Joe Grandja - * @author Craig Andrews - */ -public class HttpSessionOAuth2AuthorizationRequestRepositoryAllowMultipleAuthorizationRequestsTests - extends HttpSessionOAuth2AuthorizationRequestRepositoryTests { - - @BeforeEach - public void setup() { - this.authorizationRequestRepository = new HttpSessionOAuth2AuthorizationRequestRepository(); - this.authorizationRequestRepository.setAllowMultipleAuthorizationRequests(true); - } - - // gh-5110 - @Test - public void loadAuthorizationRequestWhenMultipleSavedThenReturnMatchingAuthorizationRequest() { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - String state1 = "state-1122"; - OAuth2AuthorizationRequest authorizationRequest1 = createAuthorizationRequest().state(state1).build(); - this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest1, request, response); - String state2 = "state-3344"; - OAuth2AuthorizationRequest authorizationRequest2 = createAuthorizationRequest().state(state2).build(); - this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest2, request, response); - String state3 = "state-5566"; - OAuth2AuthorizationRequest authorizationRequest3 = createAuthorizationRequest().state(state3).build(); - this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest3, request, response); - request.addParameter(OAuth2ParameterNames.STATE, state1); - OAuth2AuthorizationRequest loadedAuthorizationRequest1 = this.authorizationRequestRepository - .loadAuthorizationRequest(request); - assertThat(loadedAuthorizationRequest1).isEqualTo(authorizationRequest1); - request.removeParameter(OAuth2ParameterNames.STATE); - request.addParameter(OAuth2ParameterNames.STATE, state2); - OAuth2AuthorizationRequest loadedAuthorizationRequest2 = this.authorizationRequestRepository - .loadAuthorizationRequest(request); - assertThat(loadedAuthorizationRequest2).isEqualTo(authorizationRequest2); - request.removeParameter(OAuth2ParameterNames.STATE); - request.addParameter(OAuth2ParameterNames.STATE, state3); - OAuth2AuthorizationRequest loadedAuthorizationRequest3 = this.authorizationRequestRepository - .loadAuthorizationRequest(request); - assertThat(loadedAuthorizationRequest3).isEqualTo(authorizationRequest3); - } - - @Test - public void loadAuthorizationRequestWhenSavedWithAllowMultipleAuthorizationRequests() { - // save 2 requests with legacy (allowMultipleAuthorizationRequests=true) and load - // with new - HttpSessionOAuth2AuthorizationRequestRepository legacy = new HttpSessionOAuth2AuthorizationRequestRepository(); - legacy.setAllowMultipleAuthorizationRequests(true); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - String state1 = "state-1122"; - OAuth2AuthorizationRequest authorizationRequest1 = createAuthorizationRequest().state(state1).build(); - legacy.saveAuthorizationRequest(authorizationRequest1, request, response); - String state2 = "state-3344"; - OAuth2AuthorizationRequest authorizationRequest2 = createAuthorizationRequest().state(state2).build(); - legacy.saveAuthorizationRequest(authorizationRequest2, request, response); - - request.setParameter(OAuth2ParameterNames.STATE, state1); - OAuth2AuthorizationRequest loaded = this.authorizationRequestRepository.loadAuthorizationRequest(request); - - assertThat(loaded).isEqualTo(authorizationRequest1); - } - - @Test - public void saveAuthorizationRequestWhenSavedWithAllowMultipleAuthorizationRequests() { - // save 2 requests with legacy (allowMultipleAuthorizationRequests=true), save - // with new, and load with new - HttpSessionOAuth2AuthorizationRequestRepository legacy = new HttpSessionOAuth2AuthorizationRequestRepository(); - legacy.setAllowMultipleAuthorizationRequests(true); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - String state1 = "state-1122"; - OAuth2AuthorizationRequest authorizationRequest1 = createAuthorizationRequest().state(state1).build(); - legacy.saveAuthorizationRequest(authorizationRequest1, request, response); - String state2 = "state-3344"; - OAuth2AuthorizationRequest authorizationRequest2 = createAuthorizationRequest().state(state2).build(); - legacy.saveAuthorizationRequest(authorizationRequest2, request, response); - String state3 = "state-5566"; - OAuth2AuthorizationRequest authorizationRequest3 = createAuthorizationRequest().state(state3).build(); - - this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest3, request, response); - request.setParameter(OAuth2ParameterNames.STATE, state3); - OAuth2AuthorizationRequest loaded = this.authorizationRequestRepository.loadAuthorizationRequest(request); - - assertThat(loaded).isEqualTo(authorizationRequest3); - } - -} diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryDoNotAllowMultipleAuthorizationRequestsTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryDoNotAllowMultipleAuthorizationRequestsTests.java deleted file mode 100644 index 3c2b7a7139..0000000000 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryDoNotAllowMultipleAuthorizationRequestsTests.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * 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 - * - * https://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.springframework.security.oauth2.client.web; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; -import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HttpSessionOAuth2AuthorizationRequestRepository} when - * {@link HttpSessionOAuth2AuthorizationRequestRepository#setAllowMultipleAuthorizationRequests(boolean)} - * is disabled. - * - * @author Joe Grandja - * @author Craig Andrews - */ -public class HttpSessionOAuth2AuthorizationRequestRepositoryDoNotAllowMultipleAuthorizationRequestsTests - extends HttpSessionOAuth2AuthorizationRequestRepositoryTests { - - @BeforeEach - public void setup() { - this.authorizationRequestRepository = new HttpSessionOAuth2AuthorizationRequestRepository(); - this.authorizationRequestRepository.setAllowMultipleAuthorizationRequests(false); - } - - // gh-5145 - @Test - public void loadAuthorizationRequestWhenMultipleSavedThenReturnLastAuthorizationRequest() { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - String state1 = "state-1122"; - OAuth2AuthorizationRequest authorizationRequest1 = createAuthorizationRequest().state(state1).build(); - this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest1, request, response); - String state2 = "state-3344"; - OAuth2AuthorizationRequest authorizationRequest2 = createAuthorizationRequest().state(state2).build(); - this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest2, request, response); - String state3 = "state-5566"; - OAuth2AuthorizationRequest authorizationRequest3 = createAuthorizationRequest().state(state3).build(); - this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest3, request, response); - request.addParameter(OAuth2ParameterNames.STATE, state1); - OAuth2AuthorizationRequest loadedAuthorizationRequest1 = this.authorizationRequestRepository - .loadAuthorizationRequest(request); - assertThat(loadedAuthorizationRequest1).isNull(); - request.removeParameter(OAuth2ParameterNames.STATE); - request.addParameter(OAuth2ParameterNames.STATE, state2); - OAuth2AuthorizationRequest loadedAuthorizationRequest2 = this.authorizationRequestRepository - .loadAuthorizationRequest(request); - assertThat(loadedAuthorizationRequest2).isNull(); - request.removeParameter(OAuth2ParameterNames.STATE); - request.addParameter(OAuth2ParameterNames.STATE, state3); - OAuth2AuthorizationRequest loadedAuthorizationRequest3 = this.authorizationRequestRepository - .loadAuthorizationRequest(request); - assertThat(loadedAuthorizationRequest3).isEqualTo(authorizationRequest3); - } - -} diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryTests.java index 4bd6e2e2ce..ae6bfef7cd 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/HttpSessionOAuth2AuthorizationRequestRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,6 @@ import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -38,10 +36,9 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException * @author Joe Grandja * @author Craig Andrews */ -@ExtendWith(MockitoExtension.class) -public abstract class HttpSessionOAuth2AuthorizationRequestRepositoryTests { +public class HttpSessionOAuth2AuthorizationRequestRepositoryTests { - protected HttpSessionOAuth2AuthorizationRequestRepository authorizationRequestRepository; + private HttpSessionOAuth2AuthorizationRequestRepository authorizationRequestRepository = new HttpSessionOAuth2AuthorizationRequestRepository(); @Test public void loadAuthorizationRequestWhenHttpServletRequestIsNullThenThrowIllegalArgumentException() { diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryAllowMultipleAuthorizationRequestsTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryAllowMultipleAuthorizationRequestsTests.java deleted file mode 100644 index a13374e25e..0000000000 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryAllowMultipleAuthorizationRequestsTests.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * 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 - * - * https://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.springframework.security.oauth2.client.web.server; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.http.codec.ServerCodecConfigurer; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerHttpResponse; -import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; -import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebSession; -import org.springframework.web.server.adapter.DefaultServerWebExchange; -import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver; -import org.springframework.web.server.session.WebSessionManager; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * Tests for {@link WebSessionOAuth2ServerAuthorizationRequestRepository} when - * {@link WebSessionOAuth2ServerAuthorizationRequestRepository#setAllowMultipleAuthorizationRequests(boolean)} - * is enabled. - * - * @author Steve Riesenberg - */ - -public class WebSessionOAuth2ServerAuthorizationRequestRepositoryAllowMultipleAuthorizationRequestsTests - extends WebSessionOAuth2ServerAuthorizationRequestRepositoryTests { - - @BeforeEach - public void setup() { - this.repository = new WebSessionOAuth2ServerAuthorizationRequestRepository(); - this.repository.setAllowMultipleAuthorizationRequests(true); - } - - @Test - public void loadAuthorizationRequestWhenMultipleSavedThenAuthorizationRequest() { - String oldState = "state0"; - // @formatter:off - MockServerHttpRequest oldRequest = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, oldState) - .build(); - OAuth2AuthorizationRequest oldAuthorizationRequest = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(oldState) - .build(); - // @formatter:on - WebSessionManager sessionManager = (e) -> this.exchange.getSession(); - this.exchange = new DefaultServerWebExchange(this.exchange.getRequest(), new MockServerHttpResponse(), - sessionManager, ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); - ServerWebExchange oldExchange = new DefaultServerWebExchange(oldRequest, new MockServerHttpResponse(), - sessionManager, ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); - // @formatter:off - Mono saveAndSaveAndLoad = this.repository - .saveAuthorizationRequest(oldAuthorizationRequest, oldExchange) - .then(this.repository.saveAuthorizationRequest(this.authorizationRequest, this.exchange)) - .then(this.repository.loadAuthorizationRequest(oldExchange)); - StepVerifier.create(saveAndSaveAndLoad) - .expectNext(oldAuthorizationRequest) - .verifyComplete(); - StepVerifier.create(this.repository.loadAuthorizationRequest(this.exchange)) - .expectNext(this.authorizationRequest) - .verifyComplete(); - // @formatter:on - } - - // gh-5145 - @Test - public void loadAuthorizationRequestWhenSavedWithAllowMultipleAuthorizationRequestsThenReturnOldAuthorizationRequest() { - // save 2 requests with legacy (allowMultipleAuthorizationRequests=true) and load - // with new - WebSessionOAuth2ServerAuthorizationRequestRepository legacy = new WebSessionOAuth2ServerAuthorizationRequestRepository(); - legacy.setAllowMultipleAuthorizationRequests(true); - // @formatter:off - String state1 = "state-1122"; - OAuth2AuthorizationRequest authorizationRequest1 = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(state1) - .build(); - StepVerifier.create(legacy.saveAuthorizationRequest(authorizationRequest1, this.exchange)) - .verifyComplete(); - String state2 = "state-3344"; - OAuth2AuthorizationRequest authorizationRequest2 = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(state2) - .build(); - StepVerifier.create(legacy.saveAuthorizationRequest(authorizationRequest2, this.exchange)) - .verifyComplete(); - ServerHttpRequest newRequest = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, state1) - .build(); - ServerWebExchange newExchange = this.exchange.mutate() - .request(newRequest) - .build(); - StepVerifier.create(this.repository.loadAuthorizationRequest(newExchange)) - .expectNext(authorizationRequest1) - .verifyComplete(); - // @formatter:on - } - - // gh-5145 - @Test - public void saveAuthorizationRequestWhenSavedWithAllowMultipleAuthorizationRequestsThenLoadNewAuthorizationRequest() { - // save 2 requests with legacy (allowMultipleAuthorizationRequests=true), save - // with new, and load with new - WebSessionOAuth2ServerAuthorizationRequestRepository legacy = new WebSessionOAuth2ServerAuthorizationRequestRepository(); - legacy.setAllowMultipleAuthorizationRequests(true); - // @formatter:off - String state1 = "state-1122"; - OAuth2AuthorizationRequest authorizationRequest1 = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(state1) - .build(); - StepVerifier.create(legacy.saveAuthorizationRequest(authorizationRequest1, this.exchange)) - .verifyComplete(); - String state2 = "state-3344"; - OAuth2AuthorizationRequest authorizationRequest2 = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(state2) - .build(); - StepVerifier.create(legacy.saveAuthorizationRequest(authorizationRequest2, this.exchange)) - .verifyComplete(); - String state3 = "state-5566"; - OAuth2AuthorizationRequest authorizationRequest3 = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(state3) - .build(); - ServerHttpRequest newRequest = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, state3) - .build(); - ServerWebExchange newExchange = this.exchange.mutate() - .request(newRequest) - .build(); - Mono saveAndLoad = this.repository - .saveAuthorizationRequest(authorizationRequest3, this.exchange) - .then(this.repository.loadAuthorizationRequest(newExchange)); - StepVerifier.create(saveAndLoad) - .expectNext(authorizationRequest3) - .verifyComplete(); - // @formatter:on - } - - @Test - public void removeAuthorizationRequestWhenMultipleThenOnlyOneRemoved() { - String oldState = "state0"; - // @formatter:off - MockServerHttpRequest oldRequest = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, oldState) - .build(); - OAuth2AuthorizationRequest oldAuthorizationRequest = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(oldState) - .build(); - // @formatter:on - WebSessionManager sessionManager = (e) -> this.exchange.getSession(); - this.exchange = new DefaultServerWebExchange(this.exchange.getRequest(), new MockServerHttpResponse(), - sessionManager, ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); - ServerWebExchange oldExchange = new DefaultServerWebExchange(oldRequest, new MockServerHttpResponse(), - sessionManager, ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); - // @formatter:off - Mono saveAndSaveAndRemove = this.repository - .saveAuthorizationRequest(oldAuthorizationRequest, oldExchange) - .then(this.repository.saveAuthorizationRequest(this.authorizationRequest, this.exchange)) - .then(this.repository.removeAuthorizationRequest(this.exchange)); - StepVerifier.create(saveAndSaveAndRemove).expectNext(this.authorizationRequest) - .verifyComplete(); - StepVerifier.create(this.repository.loadAuthorizationRequest(this.exchange)) - .verifyComplete(); - StepVerifier.create(this.repository.loadAuthorizationRequest(oldExchange)) - .expectNext(oldAuthorizationRequest) - .verifyComplete(); - // @formatter:on - } - - // gh-7327 - @Test - public void removeAuthorizationRequestWhenMultipleThenRemovedAndSessionAttributeUpdated() { - String oldState = "state0"; - // @formatter:off - MockServerHttpRequest oldRequest = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, oldState) - .build(); - OAuth2AuthorizationRequest oldAuthorizationRequest = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(oldState) - .build(); - // @formatter:on - Map sessionAttrs = spy(new HashMap<>()); - WebSession session = mock(WebSession.class); - given(session.getAttributes()).willReturn(sessionAttrs); - WebSessionManager sessionManager = (e) -> Mono.just(session); - this.exchange = new DefaultServerWebExchange(this.exchange.getRequest(), new MockServerHttpResponse(), - sessionManager, ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); - ServerWebExchange oldExchange = new DefaultServerWebExchange(oldRequest, new MockServerHttpResponse(), - sessionManager, ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); - // @formatter:off - Mono saveAndSaveAndRemove = this.repository - .saveAuthorizationRequest(oldAuthorizationRequest, oldExchange) - .then(this.repository.saveAuthorizationRequest(this.authorizationRequest, this.exchange)) - .then(this.repository.removeAuthorizationRequest(this.exchange)); - StepVerifier.create(saveAndSaveAndRemove).expectNext(this.authorizationRequest) - .verifyComplete(); - StepVerifier.create(this.repository.loadAuthorizationRequest(this.exchange)) - .verifyComplete(); - // @formatter:on - verify(sessionAttrs, times(3)).put(any(), any()); - } - -} diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryDoNotAllowMultipleAuthorizationRequestsTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryDoNotAllowMultipleAuthorizationRequestsTests.java deleted file mode 100644 index f769d2c8ac..0000000000 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryDoNotAllowMultipleAuthorizationRequestsTests.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * 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 - * - * https://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.springframework.security.oauth2.client.web.server; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.http.codec.ServerCodecConfigurer; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerHttpResponse; -import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; -import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebSession; -import org.springframework.web.server.adapter.DefaultServerWebExchange; -import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver; -import org.springframework.web.server.session.WebSessionManager; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * Tests for {@link WebSessionOAuth2ServerAuthorizationRequestRepository} when - * {@link WebSessionOAuth2ServerAuthorizationRequestRepository#setAllowMultipleAuthorizationRequests(boolean)} - * is disabled. - * - * @author Steve Riesenberg - */ -public class WebSessionOAuth2ServerAuthorizationRequestRepositoryDoNotAllowMultipleAuthorizationRequestsTests - extends WebSessionOAuth2ServerAuthorizationRequestRepositoryTests { - - @BeforeEach - public void setup() { - this.repository = new WebSessionOAuth2ServerAuthorizationRequestRepository(); - this.repository.setAllowMultipleAuthorizationRequests(false); - } - - // gh-5145 - @Test - public void loadAuthorizationRequestWhenMultipleSavedThenReturnLastAuthorizationRequest() { - // @formatter:off - String state1 = "state-1122"; - OAuth2AuthorizationRequest authorizationRequest1 = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(state1) - .build(); - StepVerifier.create(this.repository.saveAuthorizationRequest(authorizationRequest1, this.exchange)) - .verifyComplete(); - String state2 = "state-3344"; - OAuth2AuthorizationRequest authorizationRequest2 = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(state2) - .build(); - StepVerifier.create(this.repository.saveAuthorizationRequest(authorizationRequest2, this.exchange)) - .verifyComplete(); - String state3 = "state-5566"; - OAuth2AuthorizationRequest authorizationRequest3 = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(state3) - .build(); - StepVerifier.create(this.repository.saveAuthorizationRequest(authorizationRequest3, this.exchange)) - .verifyComplete(); - ServerHttpRequest newRequest1 = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, state1) - .build(); - ServerWebExchange newExchange1 = this.exchange.mutate() - .request(newRequest1) - .build(); - StepVerifier.create(this.repository.loadAuthorizationRequest(newExchange1)) - .verifyComplete(); - ServerHttpRequest newRequest2 = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, state2) - .build(); - ServerWebExchange newExchange2 = this.exchange.mutate() - .request(newRequest2) - .build(); - StepVerifier.create(this.repository.loadAuthorizationRequest(newExchange2)) - .verifyComplete(); - ServerHttpRequest newRequest3 = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, state3) - .build(); - ServerWebExchange newExchange3 = this.exchange.mutate() - .request(newRequest3) - .build(); - StepVerifier.create(this.repository.loadAuthorizationRequest(newExchange3)) - .expectNext(authorizationRequest3) - .verifyComplete(); - // @formatter:on - } - - // gh-5145 - @Test - public void removeAuthorizationRequestWhenMultipleThenSessionAttributeRemoved() { - String oldState = "state0"; - // @formatter:off - MockServerHttpRequest oldRequest = MockServerHttpRequest.get("/") - .queryParam(OAuth2ParameterNames.STATE, oldState) - .build(); - OAuth2AuthorizationRequest oldAuthorizationRequest = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri("https://example.com/oauth2/authorize") - .clientId("client-id") - .redirectUri("http://localhost/client-1") - .state(oldState) - .build(); - // @formatter:on - Map sessionAttrs = spy(new HashMap<>()); - WebSession session = mock(WebSession.class); - given(session.getAttributes()).willReturn(sessionAttrs); - WebSessionManager sessionManager = (e) -> Mono.just(session); - this.exchange = new DefaultServerWebExchange(this.exchange.getRequest(), new MockServerHttpResponse(), - sessionManager, ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); - ServerWebExchange oldExchange = new DefaultServerWebExchange(oldRequest, new MockServerHttpResponse(), - sessionManager, ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); - // @formatter:off - Mono saveAndSaveAndRemove = this.repository - .saveAuthorizationRequest(oldAuthorizationRequest, oldExchange) - .then(this.repository.saveAuthorizationRequest(this.authorizationRequest, this.exchange)) - .then(this.repository.removeAuthorizationRequest(this.exchange)); - StepVerifier.create(saveAndSaveAndRemove).expectNext(this.authorizationRequest) - .verifyComplete(); - StepVerifier.create(this.repository.loadAuthorizationRequest(this.exchange)) - .verifyComplete(); - // @formatter:on - verify(sessionAttrs, times(2)).put(anyString(), any()); - verify(sessionAttrs).remove(anyString()); - } - -} diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryTests.java index 4549f93b72..d150aa3afc 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/WebSessionOAuth2ServerAuthorizationRequestRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,12 +35,12 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException * @author Rob Winch * @since 5.1 */ -public abstract class WebSessionOAuth2ServerAuthorizationRequestRepositoryTests { +public class WebSessionOAuth2ServerAuthorizationRequestRepositoryTests { - protected WebSessionOAuth2ServerAuthorizationRequestRepository repository; + private WebSessionOAuth2ServerAuthorizationRequestRepository repository = new WebSessionOAuth2ServerAuthorizationRequestRepository(); // @formatter:off - protected OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode() + private OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode() .authorizationUri("https://example.com/oauth2/authorize") .clientId("client-id") .redirectUri("http://localhost/client-1") @@ -48,7 +48,7 @@ public abstract class WebSessionOAuth2ServerAuthorizationRequestRepositoryTests .build(); // @formatter:on - protected ServerWebExchange exchange = MockServerWebExchange + private ServerWebExchange exchange = MockServerWebExchange .from(MockServerHttpRequest.get("/").queryParam(OAuth2ParameterNames.STATE, "state")); @Test