瀏覽代碼

OAuth2ErrorHttpMessageConverter handles JSON object parameters

Fixes gh-8157
Joe Grandja 5 年之前
父節點
當前提交
93ed92cc94

+ 12 - 5
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/http/converter/OAuth2ErrorHttpMessageConverter.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2020 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.
@@ -34,6 +34,7 @@ import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * A {@link HttpMessageConverter} for an {@link OAuth2Error OAuth 2.0 Error}.
@@ -46,8 +47,8 @@ import java.util.Map;
 public class OAuth2ErrorHttpMessageConverter extends AbstractHttpMessageConverter<OAuth2Error> {
 	private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
 
-	private static final ParameterizedTypeReference<Map<String, String>> PARAMETERIZED_RESPONSE_TYPE =
-			new ParameterizedTypeReference<Map<String, String>>() {};
+	private static final ParameterizedTypeReference<Map<String, Object>> PARAMETERIZED_RESPONSE_TYPE =
+			new ParameterizedTypeReference<Map<String, Object>>() {};
 
 	private GenericHttpMessageConverter<Object> jsonMessageConverter = HttpMessageConverters.getJsonMessageConverter();
 
@@ -69,10 +70,16 @@ public class OAuth2ErrorHttpMessageConverter extends AbstractHttpMessageConverte
 			throws HttpMessageNotReadableException {
 
 		try {
+			// gh-8157
+			// Parse parameter values as Object in order to handle potential JSON Object and then convert values to String
 			@SuppressWarnings("unchecked")
-			Map<String, String> errorParameters = (Map<String, String>) this.jsonMessageConverter.read(
+			Map<String, Object> errorParameters = (Map<String, Object>) this.jsonMessageConverter.read(
 					PARAMETERIZED_RESPONSE_TYPE.getType(), null, inputMessage);
-			return this.errorConverter.convert(errorParameters);
+			return this.errorConverter.convert(
+					errorParameters.entrySet().stream()
+							.collect(Collectors.toMap(
+									Map.Entry::getKey,
+									entry -> String.valueOf(entry.getValue()))));
 		} catch (Exception ex) {
 			throw new HttpMessageNotReadableException("An error occurred reading the OAuth 2.0 Error: " +
 					ex.getMessage(), ex, inputMessage);

+ 20 - 1
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/http/converter/OAuth2ErrorHttpMessageConverterTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2020 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.
@@ -78,6 +78,25 @@ public class OAuth2ErrorHttpMessageConverterTests {
 		assertThat(oauth2Error.getUri()).isEqualTo("https://tools.ietf.org/html/rfc6749#section-5.2");
 	}
 
+	// gh-8157
+	@Test
+	public void readInternalWhenErrorResponseWithObjectThenReadOAuth2Error() throws Exception {
+		String errorResponse = "{\n" +
+				"	\"error\": \"unauthorized_client\",\n" +
+				"   \"error_description\": \"The client is not authorized\",\n" +
+				"   \"error_codes\": [65001],\n" +
+				"   \"error_uri\": \"https://tools.ietf.org/html/rfc6749#section-5.2\"\n" +
+				"}\n";
+
+		MockClientHttpResponse response = new MockClientHttpResponse(
+				errorResponse.getBytes(), HttpStatus.BAD_REQUEST);
+
+		OAuth2Error oauth2Error = this.messageConverter.readInternal(OAuth2Error.class, response);
+		assertThat(oauth2Error.getErrorCode()).isEqualTo("unauthorized_client");
+		assertThat(oauth2Error.getDescription()).isEqualTo("The client is not authorized");
+		assertThat(oauth2Error.getUri()).isEqualTo("https://tools.ietf.org/html/rfc6749#section-5.2");
+	}
+
 	@Test
 	public void readInternalWhenConversionFailsThenThrowHttpMessageNotReadableException() {
 		Converter errorConverter = mock(Converter.class);