فهرست منبع

Allow null or empty authorities for DefaultOAuth2User

Make DefaultOAuth2User more inline with other part of
spring-security.
For example,
- DefaultOAuth2AuthenticatedPrincipal
- AbstractAuthenticationToken

Closes gh-9366
Joe Grandja 4 سال پیش
والد
کامیت
542c625d7d

+ 8 - 4
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/DefaultOAuth2User.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * 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.
@@ -30,6 +30,8 @@ import java.util.SortedSet;
 import java.util.Comparator;
 import java.util.LinkedHashSet;
 
+import org.springframework.security.core.authority.AuthorityUtils;
+
 /**
  * The default implementation of an {@link OAuth2User}.
  *
@@ -59,14 +61,16 @@ public class DefaultOAuth2User implements OAuth2User, Serializable {
 	 * @param attributes       the attributes about the user
 	 * @param nameAttributeKey the key used to access the user's "name" from {@link #getAttributes()}
 	 */
-	public DefaultOAuth2User(Collection<? extends GrantedAuthority> authorities, Map<String, Object> attributes, String nameAttributeKey) {
-		Assert.notEmpty(authorities, "authorities cannot be empty");
+	public DefaultOAuth2User(Collection<? extends GrantedAuthority> authorities, Map<String, Object> attributes,
+			String nameAttributeKey) {
 		Assert.notEmpty(attributes, "attributes cannot be empty");
 		Assert.hasText(nameAttributeKey, "nameAttributeKey cannot be empty");
 		if (!attributes.containsKey(nameAttributeKey)) {
 			throw new IllegalArgumentException("Missing attribute '" + nameAttributeKey + "' in attributes");
 		}
-		this.authorities = Collections.unmodifiableSet(new LinkedHashSet<>(this.sortAuthorities(authorities)));
+		this.authorities = (authorities != null)
+				? Collections.unmodifiableSet(new LinkedHashSet<>(this.sortAuthorities(authorities)))
+				: Collections.unmodifiableSet(new LinkedHashSet<>(AuthorityUtils.NO_AUTHORITIES));
 		this.attributes = Collections.unmodifiableMap(new LinkedHashMap<>(attributes));
 		this.nameAttributeKey = nameAttributeKey;
 	}

+ 22 - 6
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/DefaultOidcUserTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2017 the original author or authors.
+ * 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.
@@ -18,6 +18,7 @@ package org.springframework.security.oauth2.core.oidc.user;
 
 import org.junit.Test;
 import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
 import org.springframework.security.oauth2.core.oidc.OidcIdToken;
@@ -57,11 +58,6 @@ public class DefaultOidcUserTests {
 	private static final OidcIdToken ID_TOKEN = new OidcIdToken("id-token-value", Instant.EPOCH, Instant.MAX, ID_TOKEN_CLAIMS);
 	private static final OidcUserInfo USER_INFO = new OidcUserInfo(USER_INFO_CLAIMS);
 
-	@Test(expected = IllegalArgumentException.class)
-	public void constructorWhenAuthoritiesIsNullThenThrowIllegalArgumentException() {
-		new DefaultOidcUser(null, ID_TOKEN);
-	}
-
 	@Test(expected = IllegalArgumentException.class)
 	public void constructorWhenIdTokenIsNullThenThrowIllegalArgumentException() {
 		new DefaultOidcUser(AUTHORITIES, null);
@@ -72,6 +68,26 @@ public class DefaultOidcUserTests {
 		new DefaultOidcUser(AUTHORITIES, ID_TOKEN, "invalid");
 	}
 
+	@Test
+	public void constructorWhenAuthoritiesIsNullThenCreatedWithEmptyAuthorities() {
+		DefaultOidcUser user = new DefaultOidcUser(null, ID_TOKEN);
+		assertThat(user.getClaims()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB);
+		assertThat(user.getIdToken()).isEqualTo(ID_TOKEN);
+		assertThat(user.getName()).isEqualTo(SUBJECT);
+		assertThat(user.getAuthorities()).isEmpty();
+		assertThat(user.getAttributes()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB);
+	}
+
+	@Test
+	public void constructorWhenAuthoritiesIsEmptyThenCreated() {
+		DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.NO_AUTHORITIES, ID_TOKEN);
+		assertThat(user.getClaims()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB);
+		assertThat(user.getIdToken()).isEqualTo(ID_TOKEN);
+		assertThat(user.getName()).isEqualTo(SUBJECT);
+		assertThat(user.getAuthorities()).isEmpty();
+		assertThat(user.getAttributes()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB);
+	}
+
 	@Test
 	public void constructorWhenAuthoritiesIdTokenProvidedThenCreated() {
 		DefaultOidcUser user = new DefaultOidcUser(AUTHORITIES, ID_TOKEN);

+ 17 - 11
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/DefaultOAuth2UserTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2017 the original author or authors.
+ * 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.
@@ -41,16 +41,6 @@ public class DefaultOAuth2UserTests {
 	private static final Map<String, Object> ATTRIBUTES = Collections.singletonMap(
 		ATTRIBUTE_NAME_KEY, USERNAME);
 
-	@Test(expected = IllegalArgumentException.class)
-	public void constructorWhenAuthoritiesIsNullThenThrowIllegalArgumentException() {
-		new DefaultOAuth2User(null, ATTRIBUTES, ATTRIBUTE_NAME_KEY);
-	}
-
-	@Test(expected = IllegalArgumentException.class)
-	public void constructorWhenAuthoritiesIsEmptyThenThrowIllegalArgumentException() {
-		new DefaultOAuth2User(Collections.emptySet(), ATTRIBUTES, ATTRIBUTE_NAME_KEY);
-	}
-
 	@Test(expected = IllegalArgumentException.class)
 	public void constructorWhenAttributesIsNullThenThrowIllegalArgumentException() {
 		new DefaultOAuth2User(AUTHORITIES, null, ATTRIBUTE_NAME_KEY);
@@ -71,6 +61,22 @@ public class DefaultOAuth2UserTests {
 		new DefaultOAuth2User(AUTHORITIES, ATTRIBUTES, "invalid");
 	}
 
+	@Test
+	public void constructorWhenAuthoritiesIsNullThenCreatedWithEmptyAuthorities() {
+		DefaultOAuth2User user = new DefaultOAuth2User(null, ATTRIBUTES, ATTRIBUTE_NAME_KEY);
+		assertThat(user.getName()).isEqualTo(USERNAME);
+		assertThat(user.getAuthorities()).isEmpty();
+		assertThat(user.getAttributes()).containsOnlyKeys(ATTRIBUTE_NAME_KEY);
+	}
+
+	@Test
+	public void constructorWhenAuthoritiesIsEmptyThenCreated() {
+		DefaultOAuth2User user = new DefaultOAuth2User(Collections.emptySet(), ATTRIBUTES, ATTRIBUTE_NAME_KEY);
+		assertThat(user.getName()).isEqualTo(USERNAME);
+		assertThat(user.getAuthorities()).isEmpty();
+		assertThat(user.getAttributes()).containsOnlyKeys(ATTRIBUTE_NAME_KEY);
+	}
+
 	@Test
 	public void constructorWhenAllParametersProvidedAndValidThenCreated() {
 		DefaultOAuth2User user = new DefaultOAuth2User(AUTHORITIES, ATTRIBUTES, ATTRIBUTE_NAME_KEY);