diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index 5a45222c216c..438aa095c637 100644 --- a/sdk/spring/CHANGELOG.md +++ b/sdk/spring/CHANGELOG.md @@ -5,6 +5,7 @@ Upgrade Spring Boot dependencies version to 2.7.4 and Spring Cloud dependencies #### Bugs Fixed - Fix bug: Put a value into Collections.emptyMap(). [#31190](https://github.com/Azure/azure-sdk-for-java/issues/31190). +- Fix bug: Duplicated "scope" parameter. [#31191](https://github.com/Azure/azure-sdk-for-java/issues/31191). ## 4.4.0 (2022-09-26) Upgrade Spring Boot dependencies version to 2.7.3 and Spring Cloud dependencies version to 2021.0.3 diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/aad/implementation/oauth2/AbstractOAuth2AuthorizationCodeGrantRequestEntityConverter.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/aad/implementation/oauth2/AbstractOAuth2AuthorizationCodeGrantRequestEntityConverter.java index af91381bb842..eefe948c4e36 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/aad/implementation/oauth2/AbstractOAuth2AuthorizationCodeGrantRequestEntityConverter.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/aad/implementation/oauth2/AbstractOAuth2AuthorizationCodeGrantRequestEntityConverter.java @@ -4,12 +4,11 @@ package com.azure.spring.cloud.autoconfigure.aad.implementation.oauth2; import com.azure.spring.cloud.core.implementation.util.AzureSpringIdentifier; -import org.springframework.core.convert.converter.Converter; import org.springframework.http.HttpHeaders; -import org.springframework.http.RequestEntity; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequestEntityConverter; import org.springframework.util.MultiValueMap; +import org.springframework.util.MultiValueMapAdapter; import java.util.Collections; import java.util.UUID; @@ -20,6 +19,14 @@ public abstract class AbstractOAuth2AuthorizationCodeGrantRequestEntityConverter extends OAuth2AuthorizationCodeGrantRequestEntityConverter { + private static final MultiValueMap EMPTY_MULTI_VALUE_MAP = + new MultiValueMapAdapter<>(Collections.emptyMap()); + + protected AbstractOAuth2AuthorizationCodeGrantRequestEntityConverter() { + addHeadersConverter(this::getHttpHeaders); + addParametersConverter(this::getHttpBody); + } + /** * Gets the application ID. * @@ -27,23 +34,11 @@ public abstract class AbstractOAuth2AuthorizationCodeGrantRequestEntityConverter */ protected abstract String getApplicationId(); - @Override - @SuppressWarnings("unchecked") - public RequestEntity convert(OAuth2AuthorizationCodeGrantRequest request) { - addHeadersConverter(headersConverter); - addParametersConverter(parametersConverter); - return super.convert(request); - } - - private final Converter headersConverter = (request) -> getHttpHeaders(); - - private final Converter> parametersConverter = this::getHttpBody; - /** * Additional default headers information. * @return HttpHeaders */ - public HttpHeaders getHttpHeaders() { + protected HttpHeaders getHttpHeaders(OAuth2AuthorizationCodeGrantRequest request) { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.put("x-client-SKU", Collections.singletonList(getApplicationId())); httpHeaders.put("x-client-VER", Collections.singletonList(AzureSpringIdentifier.VERSION)); @@ -56,7 +51,7 @@ public HttpHeaders getHttpHeaders() { * @param request OAuth2AuthorizationCodeGrantRequest * @return MultiValueMap */ - public MultiValueMap getHttpBody(OAuth2AuthorizationCodeGrantRequest request) { - return null; + protected MultiValueMap getHttpBody(OAuth2AuthorizationCodeGrantRequest request) { + return EMPTY_MULTI_VALUE_MAP; } } diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/aad/implementation/webapp/AadOAuth2AuthorizationCodeGrantRequestEntityConverterTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/aad/implementation/webapp/AadOAuth2AuthorizationCodeGrantRequestEntityConverterTests.java index 1e110859858b..126d019049f0 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/aad/implementation/webapp/AadOAuth2AuthorizationCodeGrantRequestEntityConverterTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/aad/implementation/webapp/AadOAuth2AuthorizationCodeGrantRequestEntityConverterTests.java @@ -5,7 +5,7 @@ import com.azure.spring.cloud.autoconfigure.aad.AadClientRegistrationRepository; import com.azure.spring.cloud.autoconfigure.aad.implementation.WebApplicationContextRunnerUtils; -import org.hamcrest.Matcher; +import com.azure.spring.cloud.core.implementation.util.AzureSpringIdentifier; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.http.HttpEntity; @@ -19,12 +19,12 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse; import org.springframework.util.MultiValueMap; +import java.util.Collections; import java.util.Optional; import static com.azure.spring.cloud.autoconfigure.aad.AadClientRegistrationRepository.AZURE_CLIENT_REGISTRATION_ID; -import static org.hamcrest.CoreMatchers.hasItems; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; class AadOAuth2AuthorizationCodeGrantRequestEntityConverterTests { @@ -62,26 +62,41 @@ void addScopeForAuthorizationCodeClient() { } @Test - @SuppressWarnings("unchecked") + void onlyAddScopeOnceEvenConvertMethodExecutedMultipleTimes() { + getContextRunner().run(context -> { + AadClientRegistrationRepository repository = + (AadClientRegistrationRepository) context.getBean(ClientRegistrationRepository.class); + AadOAuth2AuthorizationCodeGrantRequestEntityConverter converter = + new AadOAuth2AuthorizationCodeGrantRequestEntityConverter(repository.getAzureClientAccessTokenScopes()); + ClientRegistration azure = repository.findByRegistrationId(AZURE_CLIENT_REGISTRATION_ID); + OAuth2AuthorizationCodeGrantRequest request = createCodeGrantRequest(azure); + // Convert method execute 2 times + converter.convert(request); + RequestEntity entity = converter.convert(request); + MultiValueMap map = WebApplicationContextRunnerUtils.toMultiValueMap(entity); + assertEquals(1, map.get("scope").size()); + }); + } + + @Test void addHeadersForAzureClient() { getContextRunner().run(context -> { AadClientRegistrationRepository repository = (AadClientRegistrationRepository) context.getBean(ClientRegistrationRepository.class); ClientRegistration azure = repository.findByRegistrationId(AZURE_CLIENT_REGISTRATION_ID); HttpHeaders httpHeaders = convertedHeaderOf(repository, createCodeGrantRequest(azure)); - assertThat(httpHeaders.entrySet(), (Matcher) hasItems(expectedHeaders(repository))); + testHttpHeaders(httpHeaders); }); } @Test - @SuppressWarnings("unchecked") void addHeadersForAuthorizationCodeClient() { getContextRunner().run(context -> { AadClientRegistrationRepository repository = (AadClientRegistrationRepository) context.getBean(ClientRegistrationRepository.class); ClientRegistration arm = repository.findByRegistrationId("arm"); HttpHeaders httpHeaders = convertedHeaderOf(repository, createCodeGrantRequest(arm)); - assertThat(httpHeaders.entrySet(), (Matcher) hasItems(expectedHeaders(repository))); + testHttpHeaders(httpHeaders); }); } @@ -95,13 +110,12 @@ private HttpHeaders convertedHeaderOf(AadClientRegistrationRepository repository .orElse(null); } - private Object[] expectedHeaders(AadClientRegistrationRepository repository) { - return new AadOAuth2AuthorizationCodeGrantRequestEntityConverter(repository.getAzureClientAccessTokenScopes()) - .getHttpHeaders() - .entrySet() - .stream() - .filter(entry -> !entry.getKey().equals("client-request-id")) - .toArray(); + private void testHttpHeaders(HttpHeaders headers) { + assertTrue(headers.containsKey("x-client-SKU")); + assertEquals(Collections.singletonList(AzureSpringIdentifier.AZURE_SPRING_AAD), headers.get("x-client-SKU")); + assertTrue(headers.containsKey("x-client-VER")); + assertEquals(Collections.singletonList(AzureSpringIdentifier.VERSION), headers.get("x-client-VER")); + assertTrue(headers.containsKey("client-request-id")); } private MultiValueMap convertedBodyOf(AadClientRegistrationRepository repository,