浏览代码

ClaimAccessor.getClaimAsInstant() converts Long or Date

Fixes gh-5191, Fixes gh-5192
Joe Grandja 7 年之前
父节点
当前提交
2bd31c96ed

+ 12 - 4
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/ClaimAccessor.java

@@ -21,6 +21,7 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.time.Instant;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -81,11 +82,18 @@ public interface ClaimAccessor {
 		if (!this.containsClaim(claim)) {
 			return null;
 		}
-		try {
-			return Instant.ofEpochMilli(Long.valueOf(this.getClaimAsString(claim)));
-		} catch (NumberFormatException ex) {
-			throw new IllegalArgumentException("Unable to convert claim '" + claim + "' to Instant: " + ex.getMessage(), ex);
+		Object claimValue = this.getClaims().get(claim);
+		if (Long.class.isAssignableFrom(claimValue.getClass())) {
+			return Instant.ofEpochSecond((Long) claimValue);
+		}
+		if (Date.class.isAssignableFrom(claimValue.getClass())) {
+			return ((Date) claimValue).toInstant();
+		}
+		if (Instant.class.isAssignableFrom(claimValue.getClass())) {
+			return (Instant) claimValue;
 		}
+		throw new IllegalArgumentException("Unable to convert claim '" + claim +
+				"' of type '" + claimValue.getClass() + "' to Instant.");
 	}
 
 	/**

+ 73 - 0
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/ClaimAccessorTests.java

@@ -0,0 +1,73 @@
+/*
+ * Copyright 2002-2018 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
+ *
+ *      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.springframework.security.oauth2.core;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.time.Instant;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link ClaimAccessor}.
+ *
+ * @author Joe Grandja
+ */
+public class ClaimAccessorTests {
+	private Map<String, Object> claims = new HashMap<>();
+	private ClaimAccessor claimAccessor = (() -> this.claims);
+
+	@Before
+	public void setup() {
+		this.claims.clear();
+	}
+
+	// gh-5192
+	@Test
+	public void getClaimAsInstantWhenDateTypeThenReturnInstant() {
+		Instant expectedClaimValue = Instant.now();
+		String claimName = "date";
+		this.claims.put(claimName, Date.from(expectedClaimValue));
+
+		assertThat(this.claimAccessor.getClaimAsInstant(claimName)).isBetween(
+				expectedClaimValue.minusSeconds(1), expectedClaimValue.plusSeconds(1));
+	}
+
+	// gh-5191
+	@Test
+	public void getClaimAsInstantWhenLongTypeSecondsThenReturnInstant() {
+		Instant expectedClaimValue = Instant.now();
+		String claimName = "longSeconds";
+		this.claims.put(claimName, expectedClaimValue.getEpochSecond());
+
+		assertThat(this.claimAccessor.getClaimAsInstant(claimName)).isBetween(
+				expectedClaimValue.minusSeconds(1), expectedClaimValue.plusSeconds(1));
+	}
+
+	@Test
+	public void getClaimAsInstantWhenInstantTypeThenReturnInstant() {
+		Instant expectedClaimValue = Instant.now();
+		String claimName = "instant";
+		this.claims.put(claimName, expectedClaimValue);
+
+		assertThat(this.claimAccessor.getClaimAsInstant(claimName)).isBetween(
+				expectedClaimValue.minusSeconds(1), expectedClaimValue.plusSeconds(1));
+	}
+}

+ 1 - 1
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcIdTokenTests.java

@@ -110,7 +110,7 @@ public class OidcIdTokenTests {
 		assertThat(idToken.getAudience()).isEqualTo(AUD_VALUE);
 		assertThat(idToken.getIssuedAt().toEpochMilli()).isEqualTo(IAT_VALUE);
 		assertThat(idToken.getExpiresAt().toEpochMilli()).isEqualTo(EXP_VALUE);
-		assertThat(idToken.getAuthenticatedAt().toEpochMilli()).isEqualTo(AUTH_TIME_VALUE);
+		assertThat(idToken.getAuthenticatedAt().getEpochSecond()).isEqualTo(AUTH_TIME_VALUE);
 		assertThat(idToken.getNonce()).isEqualTo(NONCE_VALUE);
 		assertThat(idToken.getAuthenticationContextClass()).isEqualTo(ACR_VALUE);
 		assertThat(idToken.getAuthenticationMethods()).isEqualTo(AMR_VALUE);

+ 1 - 1
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcUserInfoTests.java

@@ -137,6 +137,6 @@ public class OidcUserInfoTests {
 		assertThat(userInfo.getPhoneNumber()).isEqualTo(PHONE_NUMBER_VALUE);
 		assertThat(userInfo.getPhoneNumberVerified()).isEqualTo(PHONE_NUMBER_VERIFIED_VALUE);
 		assertThat(userInfo.getAddress()).isEqualTo(new DefaultAddressStandardClaim.Builder(ADDRESS_VALUE).build());
-		assertThat(userInfo.getUpdatedAt().toEpochMilli()).isEqualTo(UPDATED_AT_VALUE);
+		assertThat(userInfo.getUpdatedAt().getEpochSecond()).isEqualTo(UPDATED_AT_VALUE);
 	}
 }

+ 1 - 1
oauth2/oauth2-jose/src/test/java/org/springframework/security/oauth2/jwt/JwtTests.java

@@ -106,7 +106,7 @@ public class JwtTests {
 		assertThat(jwt.getSubject()).isEqualTo(SUB_VALUE);
 		assertThat(jwt.getAudience()).isEqualTo(AUD_VALUE);
 		assertThat(jwt.getExpiresAt().toEpochMilli()).isEqualTo(EXP_VALUE);
-		assertThat(jwt.getNotBefore().toEpochMilli()).isEqualTo(NBF_VALUE);
+		assertThat(jwt.getNotBefore().getEpochSecond()).isEqualTo(NBF_VALUE);
 		assertThat(jwt.getIssuedAt().toEpochMilli()).isEqualTo(IAT_VALUE);
 		assertThat(jwt.getId()).isEqualTo(JTI_VALUE);
 	}