Browse Source

OAuth2AccessTokenResponseBodyExtractor supports Object values

This commit ensures the token response is parsed correctly if the values are not a String.

Fixes: gh-6087
Rafael Dominguez 6 years ago
parent
commit
75a2c2b729

+ 4 - 4
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/web/reactive/function/OAuth2AccessTokenResponseBodyExtractor.java

@@ -55,15 +55,15 @@ class OAuth2AccessTokenResponseBodyExtractor
 	@Override
 	public Mono<OAuth2AccessTokenResponse> extract(ReactiveHttpInputMessage inputMessage,
 			Context context) {
-		ParameterizedTypeReference<Map<String, String>> type = new ParameterizedTypeReference<Map<String, String>>() {};
-		BodyExtractor<Mono<Map<String, String>>, ReactiveHttpInputMessage> delegate = BodyExtractors.toMono(type);
+		ParameterizedTypeReference<Map<String, Object>> type = new ParameterizedTypeReference<Map<String, Object>>() {};
+		BodyExtractor<Mono<Map<String, Object>>, ReactiveHttpInputMessage> delegate = BodyExtractors.toMono(type);
 		return delegate.extract(inputMessage, context)
-				.map(json -> parse(json))
+				.map(OAuth2AccessTokenResponseBodyExtractor::parse)
 				.flatMap(OAuth2AccessTokenResponseBodyExtractor::oauth2AccessTokenResponse)
 				.map(OAuth2AccessTokenResponseBodyExtractor::oauth2AccessTokenResponse);
 	}
 
-	private static TokenResponse parse(Map<String, String> json) {
+	private static TokenResponse parse(Map<String, Object> json) {
 		try {
 			return TokenResponse.parse(new JSONObject(json));
 		}

+ 29 - 0
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/web/reactive/function/OAuth2BodyExtractorsTests.java

@@ -120,4 +120,33 @@ public class OAuth2BodyExtractorsTests {
 		assertThat(result.getRefreshToken().getTokenValue()).isEqualTo("tGzv3JOkF0XG5Qx2TlKWIA");
 		assertThat(result.getAdditionalParameters()).containsEntry("example_parameter", "example_value");
 	}
+
+
+	@Test
+	// gh-6087
+	public void oauth2AccessTokenResponseWhenMultipleAttributeTypesThenCreated() throws Exception {
+		BodyExtractor<Mono<OAuth2AccessTokenResponse>, ReactiveHttpInputMessage> extractor = OAuth2BodyExtractors
+				.oauth2AccessTokenResponse();
+
+		MockClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK);
+		response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+		response.setBody("{\n"
+				+ "       \"access_token\":\"2YotnFZFEjr1zCsicMWpAA\",\n"
+				+ "       \"token_type\":\"Bearer\",\n"
+				+ "       \"expires_in\":3600,\n"
+				+ "       \"refresh_token\":\"tGzv3JOkF0XG5Qx2TlKWIA\",\n"
+				+ "       \"subjson\":{}, \n"
+				+ "		  \"list\":[]  \n"
+				+ "     }");
+
+		Instant now = Instant.now();
+		OAuth2AccessTokenResponse result = extractor.extract(response, this.context).block();
+
+		assertThat(result.getAccessToken().getTokenValue()).isEqualTo("2YotnFZFEjr1zCsicMWpAA");
+		assertThat(result.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER);
+		assertThat(result.getAccessToken().getExpiresAt()).isBetween(now.plusSeconds(3600), now.plusSeconds(3600 + 2));
+		assertThat(result.getRefreshToken().getTokenValue()).isEqualTo("tGzv3JOkF0XG5Qx2TlKWIA");
+		assertThat(result.getAdditionalParameters().get("subjson")).isInstanceOfAny(Map.class);
+		assertThat(result.getAdditionalParameters().get("list")).isInstanceOfAny(List.class);
+	}
 }