فهرست منبع

Polish oauth2-core

Joe Grandja 8 سال پیش
والد
کامیت
d4d7199a6d
21فایلهای تغییر یافته به همراه244 افزوده شده و 185 حذف شده
  1. 1 1
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationRequestRedirectFilter.java
  2. 1 1
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultAuthorizationRequestUriBuilder.java
  3. 1 1
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationFilterTests.java
  4. 1 1
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationRequestRedirectFilterTests.java
  5. 21 21
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AccessToken.java
  6. 0 3
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AuthorizationGrantType.java
  7. 3 3
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/ClaimAccessor.java
  8. 1 1
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/ClientAuthenticationMethod.java
  9. 1 4
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/SecurityToken.java
  10. 40 26
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/AuthorizationRequest.java
  11. 1 1
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/ResponseType.java
  12. 4 4
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/TokenResponse.java
  13. 14 6
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/DefaultOAuth2User.java
  14. 1 1
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthority.java
  15. 0 92
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/Address.java
  16. 136 0
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/DefaultAddress.java
  17. 4 4
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/StandardClaimAccessor.java
  18. 0 1
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/user/OidcUser.java
  19. 3 3
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/user/OidcUserAuthority.java
  20. 10 10
      oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/AuthorizationRequestTest.java
  21. 1 1
      oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/oidc/core/user/DefaultOidcUserTests.java

+ 1 - 1
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationRequestRedirectFilter.java

@@ -142,7 +142,7 @@ public class AuthorizationRequestRedirectFilter extends OncePerRequestFilter {
 		}
 		AuthorizationRequest authorizationRequest = builder
 				.clientId(clientRegistration.getClientId())
-				.authorizeUri(clientRegistration.getProviderDetails().getAuthorizationUri())
+				.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri())
 				.redirectUri(redirectUriStr)
 				.scope(clientRegistration.getScope())
 				.state(this.stateGenerator.generateKey())

+ 1 - 1
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultAuthorizationRequestUriBuilder.java

@@ -37,7 +37,7 @@ public class DefaultAuthorizationRequestUriBuilder implements AuthorizationReque
 	@Override
 	public URI build(AuthorizationRequest authorizationRequest) {
 		UriComponentsBuilder uriBuilder = UriComponentsBuilder
-			.fromUriString(authorizationRequest.getAuthorizeUri())
+			.fromUriString(authorizationRequest.getAuthorizationUri())
 			.queryParam(OAuth2Parameter.RESPONSE_TYPE, authorizationRequest.getResponseType().getValue())
 			.queryParam(OAuth2Parameter.CLIENT_ID, authorizationRequest.getClientId())
 			.queryParam(OAuth2Parameter.SCOPE,

+ 1 - 1
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationFilterTests.java

@@ -199,7 +199,7 @@ public class AuthorizationCodeAuthenticationFilterTests {
 		AuthorizationRequest authorizationRequest =
 			AuthorizationRequest.authorizationCode()
 				.clientId(clientRegistration.getClientId())
-				.authorizeUri(clientRegistration.getProviderDetails().getAuthorizationUri())
+				.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri())
 				.redirectUri(clientRegistration.getRedirectUri())
 				.scope(clientRegistration.getScope())
 				.state(state)

+ 1 - 1
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationRequestRedirectFilterTests.java

@@ -104,7 +104,7 @@ public class AuthorizationRequestRedirectFilterTests {
 				authorizationRequestRepository.loadAuthorizationRequest(request);
 		Assertions.assertThat(authorizationRequest).isNotNull();
 
-		Assertions.assertThat(authorizationRequest.getAuthorizeUri()).isNotNull();
+		Assertions.assertThat(authorizationRequest.getAuthorizationUri()).isNotNull();
 		Assertions.assertThat(authorizationRequest.getGrantType()).isNotNull();
 		Assertions.assertThat(authorizationRequest.getResponseType()).isNotNull();
 		Assertions.assertThat(authorizationRequest.getClientId()).isNotNull();

+ 21 - 21
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AccessToken.java

@@ -38,11 +38,31 @@ public class AccessToken extends SecurityToken {
 	private final TokenType tokenType;
 	private final Set<String> scope;
 
+	public AccessToken(TokenType tokenType, String tokenValue, Instant issuedAt, Instant expiresAt) {
+		this(tokenType, tokenValue, issuedAt, expiresAt, Collections.emptySet());
+	}
+
+	public AccessToken(TokenType tokenType, String tokenValue, Instant issuedAt, Instant expiresAt, Set<String> scope) {
+		super(tokenValue, issuedAt, expiresAt);
+		Assert.notNull(tokenType, "tokenType cannot be null");
+		this.tokenType = tokenType;
+		this.scope = Collections.unmodifiableSet(
+			scope != null ? scope : Collections.emptySet());
+	}
+
+	public TokenType getTokenType() {
+		return this.tokenType;
+	}
+
+	public Set<String> getScope() {
+		return this.scope;
+	}
+
 	public static final class TokenType {
 		public static final TokenType BEARER = new TokenType("Bearer");
 		private final String value;
 
-		public TokenType(String value) {
+		private TokenType(String value) {
 			Assert.hasText(value, "value cannot be empty");
 			this.value = value;
 		}
@@ -68,24 +88,4 @@ public class AccessToken extends SecurityToken {
 			return this.getValue().hashCode();
 		}
 	}
-
-	public AccessToken(TokenType tokenType, String tokenValue, Instant issuedAt, Instant expiresAt) {
-		this(tokenType, tokenValue, issuedAt, expiresAt, Collections.emptySet());
-	}
-
-	public AccessToken(TokenType tokenType, String tokenValue, Instant issuedAt, Instant expiresAt, Set<String> scope) {
-		super(tokenValue, issuedAt, expiresAt);
-		Assert.notNull(tokenType, "tokenType cannot be null");
-		this.tokenType = tokenType;
-		this.scope = Collections.unmodifiableSet(
-			scope != null ? scope : Collections.emptySet());
-	}
-
-	public TokenType getTokenType() {
-		return this.tokenType;
-	}
-
-	public Set<String> getScope() {
-		return this.scope;
-	}
 }

+ 0 - 3
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AuthorizationGrantType.java

@@ -26,9 +26,6 @@ import org.springframework.util.Assert;
  * authorization code, implicit, resource owner password credentials, and client credentials.
  * It also provides an extensibility mechanism for defining additional grant types.
  *
- * <p>
- * <b>NOTE:</b> &quot;authorization code&quot; is currently the only supported grant type.
- *
  * @author Joe Grandja
  * @since 5.0
  * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-1.3">Section 1.3 Authorization Grant</a>

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

@@ -74,9 +74,9 @@ public interface ClaimAccessor {
 		if (!this.containsClaim(claim) || !Map.class.isAssignableFrom(this.getClaims().get(claim).getClass())) {
 			return null;
 		}
-		Map<String, Object> claimFields = new HashMap<>();
-		((Map<?, ?>)this.getClaims().get(claim)).forEach((k, v) -> claimFields.put(k.toString(), v));
-		return claimFields;
+		Map<String, Object> claimValues = new HashMap<>();
+		((Map<?, ?>)this.getClaims().get(claim)).forEach((k, v) -> claimValues.put(k.toString(), v));
+		return claimValues;
 	}
 
 	default List<String> getClaimAsStringList(String claim) {

+ 1 - 1
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/ClientAuthenticationMethod.java

@@ -18,7 +18,7 @@ package org.springframework.security.oauth2.core;
 import org.springframework.util.Assert;
 
 /**
- * The available authentication methods used when authenticating the client with the authorization server.
+ * The authentication methods used when authenticating the client with the authorization server.
  *
  * @author Joe Grandja
  * @since 5.0

+ 1 - 4
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/SecurityToken.java

@@ -24,9 +24,6 @@ import java.time.Instant;
 /**
  * Base class for <i>Security Token</i> implementations.
  *
- * <p>
- * It is highly recommended that implementations be immutable.
- *
  * @author Joe Grandja
  * @since 5.0
  */
@@ -37,7 +34,7 @@ public abstract class SecurityToken implements Serializable {
 	private final Instant expiresAt;
 
 	protected SecurityToken(String tokenValue, Instant issuedAt, Instant expiresAt) {
-		Assert.hasLength(tokenValue, "tokenValue cannot be empty");
+		Assert.hasText(tokenValue, "tokenValue cannot be empty");
 		Assert.notNull(issuedAt, "issuedAt cannot be null");
 		Assert.notNull(expiresAt, "expiresAt cannot be null");
 		this.tokenValue = tokenValue;

+ 40 - 26
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/AuthorizationRequest.java

@@ -38,7 +38,7 @@ import java.util.Set;
  * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.2.1">Section 4.2.1 Implicit Grant Request</a>
  */
 public final class AuthorizationRequest implements Serializable {
-	private String authorizeUri;
+	private String authorizationUri;
 	private AuthorizationGrantType authorizationGrantType;
 	private ResponseType responseType;
 	private String clientId;
@@ -50,8 +50,8 @@ public final class AuthorizationRequest implements Serializable {
 	private AuthorizationRequest() {
 	}
 
-	public String getAuthorizeUri() {
-		return this.authorizeUri;
+	public String getAuthorizationUri() {
+		return this.authorizationUri;
 	}
 
 	public AuthorizationGrantType getGrantType() {
@@ -91,62 +91,76 @@ public final class AuthorizationRequest implements Serializable {
 	}
 
 	public static class Builder {
-		private final AuthorizationRequest authorizationRequest;
+		private String authorizationUri;
+		private AuthorizationGrantType authorizationGrantType;
+		private ResponseType responseType;
+		private String clientId;
+		private String redirectUri;
+		private Set<String> scope;
+		private String state;
+		private Map<String,Object> additionalParameters;
 
 		private Builder(AuthorizationGrantType authorizationGrantType) {
 			Assert.notNull(authorizationGrantType, "authorizationGrantType cannot be null");
-			this.authorizationRequest = new AuthorizationRequest();
-			this.authorizationRequest.authorizationGrantType = authorizationGrantType;
+			this.authorizationGrantType = authorizationGrantType;
 			if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(authorizationGrantType)) {
-				this.authorizationRequest.responseType = ResponseType.CODE;
+				this.responseType = ResponseType.CODE;
 			} else if (AuthorizationGrantType.IMPLICIT.equals(authorizationGrantType)) {
-				this.authorizationRequest.responseType = ResponseType.TOKEN;
+				this.responseType = ResponseType.TOKEN;
 			}
 		}
 
-		public Builder authorizeUri(String authorizeUri) {
-			this.authorizationRequest.authorizeUri = authorizeUri;
+		public Builder authorizationUri(String authorizationUri) {
+			this.authorizationUri = authorizationUri;
 			return this;
 		}
 
 		public Builder clientId(String clientId) {
-			this.authorizationRequest.clientId = clientId;
+			this.clientId = clientId;
 			return this;
 		}
 
 		public Builder redirectUri(String redirectUri) {
-			this.authorizationRequest.redirectUri = redirectUri;
+			this.redirectUri = redirectUri;
 			return this;
 		}
 
 		public Builder scope(Set<String> scope) {
-			this.authorizationRequest.scope = scope;
+			this.scope = scope;
 			return this;
 		}
 
 		public Builder state(String state) {
-			this.authorizationRequest.state = state;
+			this.state = state;
 			return this;
 		}
 
 		public Builder additionalParameters(Map<String,Object> additionalParameters) {
-			this.authorizationRequest.additionalParameters = additionalParameters;
+			this.additionalParameters = additionalParameters;
 			return this;
 		}
 
 		public AuthorizationRequest build() {
-			Assert.hasText(this.authorizationRequest.authorizeUri, "authorizeUri cannot be empty");
-			Assert.hasText(this.authorizationRequest.clientId, "clientId cannot be empty");
-			if (AuthorizationGrantType.IMPLICIT.equals(this.authorizationRequest.authorizationGrantType)) {
-				Assert.hasText(this.authorizationRequest.redirectUri, "redirectUri cannot be empty");
+			Assert.hasText(this.authorizationUri, "authorizationUri cannot be empty");
+			Assert.hasText(this.clientId, "clientId cannot be empty");
+			if (AuthorizationGrantType.IMPLICIT.equals(this.authorizationGrantType)) {
+				Assert.hasText(this.redirectUri, "redirectUri cannot be empty");
 			}
-			this.authorizationRequest.scope = Collections.unmodifiableSet(
-				CollectionUtils.isEmpty(this.authorizationRequest.scope) ?
-					Collections.emptySet() : new LinkedHashSet<>(this.authorizationRequest.scope));
-			this.authorizationRequest.additionalParameters = Collections.unmodifiableMap(
-				CollectionUtils.isEmpty(this.authorizationRequest.additionalParameters) ?
-					Collections.emptyMap() : new LinkedHashMap<>(this.authorizationRequest.additionalParameters));
-			return this.authorizationRequest;
+
+			AuthorizationRequest authorizationRequest = new AuthorizationRequest();
+			authorizationRequest.authorizationUri = this.authorizationUri;
+			authorizationRequest.authorizationGrantType = this.authorizationGrantType;
+			authorizationRequest.responseType = this.responseType;
+			authorizationRequest.clientId = this.clientId;
+			authorizationRequest.redirectUri = this.redirectUri;
+			authorizationRequest.state = this.state;
+			authorizationRequest.scope = Collections.unmodifiableSet(
+				CollectionUtils.isEmpty(this.scope) ?
+					Collections.emptySet() : new LinkedHashSet<>(this.scope));
+			authorizationRequest.additionalParameters = Collections.unmodifiableMap(
+				CollectionUtils.isEmpty(this.additionalParameters) ?
+					Collections.emptyMap() : new LinkedHashMap<>(this.additionalParameters));
+			return authorizationRequest;
 		}
 	}
 }

+ 1 - 1
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/ResponseType.java

@@ -35,7 +35,7 @@ public final class ResponseType {
 	public static final ResponseType TOKEN = new ResponseType("token");
 	private final String value;
 
-	public ResponseType(String value) {
+	private ResponseType(String value) {
 		Assert.hasText(value, "value cannot be empty");
 		this.value = value;
 	}

+ 4 - 4
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/TokenResponse.java

@@ -17,6 +17,7 @@ package org.springframework.security.oauth2.core.endpoint;
 
 import org.springframework.security.oauth2.core.AccessToken;
 import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
 
 import java.time.Instant;
 import java.util.Collections;
@@ -100,12 +101,11 @@ public final class TokenResponse {
 		public TokenResponse build() {
 			Assert.isTrue(this.expiresIn >= 0, "expiresIn must be a positive number");
 			Instant issuedAt = Instant.now();
-			AccessToken accessToken = new AccessToken(this.tokenType, this.tokenValue, issuedAt,
-				issuedAt.plusSeconds(this.expiresIn), this.scope);
 			TokenResponse tokenResponse = new TokenResponse();
-			tokenResponse.accessToken = accessToken;
+			tokenResponse.accessToken = new AccessToken(this.tokenType, this.tokenValue, issuedAt,
+				issuedAt.plusSeconds(this.expiresIn), this.scope);
 			tokenResponse.additionalParameters = Collections.unmodifiableMap(
-				this.additionalParameters != null ? this.additionalParameters : Collections.emptyMap());
+				CollectionUtils.isEmpty(this.additionalParameters) ? Collections.emptyMap() : this.additionalParameters);
 			return tokenResponse;
 		}
 	}

+ 14 - 6
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/DefaultOAuth2User.java

@@ -19,7 +19,15 @@ import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.SpringSecurityCoreVersion;
 import org.springframework.util.Assert;
 
-import java.util.*;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
 import java.util.stream.Collectors;
 
 /**
@@ -37,10 +45,10 @@ import java.util.stream.Collectors;
  * @since 5.0
  * @see OAuth2User
  */
-public class DefaultOAuth2User implements OAuth2User {
+public class DefaultOAuth2User implements OAuth2User, Serializable {
 	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
 	private final Set<GrantedAuthority> authorities;
-	private Map<String, Object> attributes;
+	private final Map<String, Object> attributes;
 	private final String nameAttributeKey;
 
 	public DefaultOAuth2User(Set<GrantedAuthority> authorities, Map<String, Object> attributes, String nameAttributeKey) {
@@ -48,7 +56,7 @@ public class DefaultOAuth2User implements OAuth2User {
 		Assert.notEmpty(attributes, "attributes cannot be empty");
 		Assert.hasText(nameAttributeKey, "nameAttributeKey cannot be empty");
 		if (!attributes.containsKey(nameAttributeKey)) {
-			throw new IllegalArgumentException("Invalid nameAttributeKey: " + nameAttributeKey);
+			throw new IllegalArgumentException("Missing attribute '" + nameAttributeKey + "' in attributes");
 		}
 		this.authorities = Collections.unmodifiableSet(this.sortAuthorities(authorities));
 		this.attributes = Collections.unmodifiableMap(new LinkedHashMap<>(attributes));
@@ -72,8 +80,8 @@ public class DefaultOAuth2User implements OAuth2User {
 
 	private Set<GrantedAuthority> sortAuthorities(Set<GrantedAuthority> authorities) {
 		SortedSet<GrantedAuthority> sortedAuthorities =
-			new TreeSet<>((g1, g2) -> g1.getAuthority().compareTo(g2.getAuthority()));
-		authorities.stream().forEach(sortedAuthorities::add);
+			new TreeSet<>(Comparator.comparing(GrantedAuthority::getAuthority));
+		sortedAuthorities.addAll(authorities);
 		return sortedAuthorities;
 	}
 

+ 1 - 1
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthority.java

@@ -33,7 +33,7 @@ import java.util.Map;
 public class OAuth2UserAuthority implements GrantedAuthority {
 	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
 	private final String authority;
-	private Map<String, Object> attributes;
+	private final Map<String, Object> attributes;
 
 	public OAuth2UserAuthority(Map<String, Object> attributes) {
 		this("ROLE_USER", attributes);

+ 0 - 92
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/Address.java

@@ -15,8 +15,6 @@
  */
 package org.springframework.security.oauth2.oidc.core;
 
-import java.util.Map;
-
 /**
  * The Address Claim represents a physical mailing address defined by the <i>OpenID Connect Core 1.0</i> specification
  * that can be returned either in the <i>UserInfo Response</i> or the <i>ID Token</i>.
@@ -41,94 +39,4 @@ public interface Address {
 
 	String getCountry();
 
-	class Builder implements Address {
-		private static final String FORMATTED_FIELD_NAME = "formatted";
-		private static final String STREET_ADDRESS_FIELD_NAME = "street_address";
-		private static final String LOCALITY_FIELD_NAME = "locality";
-		private static final String REGION_FIELD_NAME = "region";
-		private static final String POSTAL_CODE_FIELD_NAME = "postal_code";
-		private static final String COUNTRY_FIELD_NAME = "country";
-		private String formatted;
-		private String streetAddress;
-		private String locality;
-		private String region;
-		private String postalCode;
-		private String country;
-
-		public Builder() {
-		}
-
-		public Builder(Map<String, Object> addressFields) {
-			this.formatted((String)addressFields.get(FORMATTED_FIELD_NAME));
-			this.streetAddress((String)addressFields.get(STREET_ADDRESS_FIELD_NAME));
-			this.locality((String)addressFields.get(LOCALITY_FIELD_NAME));
-			this.region((String)addressFields.get(REGION_FIELD_NAME));
-			this.postalCode((String)addressFields.get(POSTAL_CODE_FIELD_NAME));
-			this.country((String)addressFields.get(COUNTRY_FIELD_NAME));
-		}
-
-		public Builder formatted(String formatted) {
-			this.formatted = formatted;
-			return this;
-		}
-
-		public Builder streetAddress(String streetAddress) {
-			this.streetAddress = streetAddress;
-			return this;
-		}
-
-		public Builder locality(String locality) {
-			this.locality = locality;
-			return this;
-		}
-
-		public Builder region(String region) {
-			this.region = region;
-			return this;
-		}
-
-		public Builder postalCode(String postalCode) {
-			this.postalCode = postalCode;
-			return this;
-		}
-
-		public Builder country(String country) {
-			this.country = country;
-			return this;
-		}
-
-		public Address build() {
-			return this;
-		}
-
-		@Override
-		public String getFormatted() {
-			return this.formatted;
-		}
-
-		@Override
-		public String getStreetAddress() {
-			return this.streetAddress;
-		}
-
-		@Override
-		public String getLocality() {
-			return this.locality;
-		}
-
-		@Override
-		public String getRegion() {
-			return this.region;
-		}
-
-		@Override
-		public String getPostalCode() {
-			return this.postalCode;
-		}
-
-		@Override
-		public String getCountry() {
-			return this.country;
-		}
-	}
 }

+ 136 - 0
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/DefaultAddress.java

@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012-2017 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.oidc.core;
+
+import java.util.Map;
+
+/**
+ * The default implementation of an {@link Address}.
+ *
+ * @author Joe Grandja
+ * @since 5.0
+ * @see Address
+ */
+public final class DefaultAddress implements Address {
+	private String formatted;
+	private String streetAddress;
+	private String locality;
+	private String region;
+	private String postalCode;
+	private String country;
+
+	private DefaultAddress() {
+	}
+
+	@Override
+	public String getFormatted() {
+		return this.formatted;
+	}
+
+	@Override
+	public String getStreetAddress() {
+		return this.streetAddress;
+	}
+
+	@Override
+	public String getLocality() {
+		return this.locality;
+	}
+
+	@Override
+	public String getRegion() {
+		return this.region;
+	}
+
+	@Override
+	public String getPostalCode() {
+		return this.postalCode;
+	}
+
+	@Override
+	public String getCountry() {
+		return this.country;
+	}
+
+	public static class Builder {
+		private static final String FORMATTED_FIELD_NAME = "formatted";
+		private static final String STREET_ADDRESS_FIELD_NAME = "street_address";
+		private static final String LOCALITY_FIELD_NAME = "locality";
+		private static final String REGION_FIELD_NAME = "region";
+		private static final String POSTAL_CODE_FIELD_NAME = "postal_code";
+		private static final String COUNTRY_FIELD_NAME = "country";
+		private String formatted;
+		private String streetAddress;
+		private String locality;
+		private String region;
+		private String postalCode;
+		private String country;
+
+		public Builder() {
+		}
+
+		public Builder(Map<String, Object> addressFields) {
+			this.formatted((String)addressFields.get(FORMATTED_FIELD_NAME));
+			this.streetAddress((String)addressFields.get(STREET_ADDRESS_FIELD_NAME));
+			this.locality((String)addressFields.get(LOCALITY_FIELD_NAME));
+			this.region((String)addressFields.get(REGION_FIELD_NAME));
+			this.postalCode((String)addressFields.get(POSTAL_CODE_FIELD_NAME));
+			this.country((String)addressFields.get(COUNTRY_FIELD_NAME));
+		}
+
+		public Builder formatted(String formatted) {
+			this.formatted = formatted;
+			return this;
+		}
+
+		public Builder streetAddress(String streetAddress) {
+			this.streetAddress = streetAddress;
+			return this;
+		}
+
+		public Builder locality(String locality) {
+			this.locality = locality;
+			return this;
+		}
+
+		public Builder region(String region) {
+			this.region = region;
+			return this;
+		}
+
+		public Builder postalCode(String postalCode) {
+			this.postalCode = postalCode;
+			return this;
+		}
+
+		public Builder country(String country) {
+			this.country = country;
+			return this;
+		}
+
+		public Address build() {
+			DefaultAddress address = new DefaultAddress();
+			address.formatted = this.formatted;
+			address.streetAddress = this.streetAddress;
+			address.locality = this.locality;
+			address.region = this.region;
+			address.postalCode = this.postalCode;
+			address.country = this.country;
+
+			return address;
+		}
+	}
+}

+ 4 - 4
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/StandardClaimAccessor.java

@@ -16,6 +16,7 @@
 package org.springframework.security.oauth2.oidc.core;
 
 import org.springframework.security.oauth2.core.ClaimAccessor;
+import org.springframework.util.CollectionUtils;
 
 import java.time.Instant;
 import java.util.Map;
@@ -28,7 +29,6 @@ import java.util.Map;
  * @see StandardClaim
  * @see UserInfo
  * @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse">UserInfo Response</a>
- * @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#IDToken">ID Token</a>
  * @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims">Standard Claims</a>
  * @author Joe Grandja
  * @since 5.0
@@ -109,9 +109,9 @@ public interface StandardClaimAccessor extends ClaimAccessor {
 
 	default Address getAddress() {
 		Map<String, Object> addressFields = this.getClaimAsMap(StandardClaim.ADDRESS);
-		return (addressFields != null ?
-			new Address.Builder(addressFields).build() :
-			new Address.Builder().build());
+		return (!CollectionUtils.isEmpty(addressFields) ?
+			new DefaultAddress.Builder(addressFields).build() :
+			new DefaultAddress.Builder().build());
 	}
 
 	default Instant getUpdatedAt() {

+ 0 - 1
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/user/OidcUser.java

@@ -48,7 +48,6 @@ import java.util.Map;
  * @see UserInfo
  * @see IdTokenClaimAccessor
  * @see StandardClaimAccessor
- * @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html">OpenID Connect Core 1.0</a>
  * @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#IDToken">ID Token</a>
  * @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims">Standard Claims</a>
  */

+ 3 - 3
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/oidc/core/user/OidcUserAuthority.java

@@ -16,7 +16,6 @@
 package org.springframework.security.oauth2.oidc.core.user;
 
 import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.SpringSecurityCoreVersion;
 import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
 import org.springframework.security.oauth2.oidc.core.IdToken;
 import org.springframework.security.oauth2.oidc.core.UserInfo;
@@ -29,7 +28,6 @@ import org.springframework.security.oauth2.oidc.core.UserInfo;
  * @see OidcUser
  */
 public class OidcUserAuthority extends OAuth2UserAuthority {
-	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
 	private final IdToken idToken;
 	private final UserInfo userInfo;
 
@@ -72,7 +70,9 @@ public class OidcUserAuthority extends OAuth2UserAuthority {
 		if (!this.getIdToken().equals(that.getIdToken())) {
 			return false;
 		}
-		return this.getUserInfo() != null ? this.getUserInfo().equals(that.getUserInfo()) : that.getUserInfo() == null;
+		return this.getUserInfo() != null ?
+			this.getUserInfo().equals(that.getUserInfo()) :
+			that.getUserInfo() == null;
 	}
 
 	@Override

+ 10 - 10
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/AuthorizationRequestTest.java

@@ -38,7 +38,7 @@ public class AuthorizationRequestTest {
 	@Test(expected = IllegalArgumentException.class)
 	public void buildWhenAuthorizationUriIsNullThenThrowIllegalArgumentException() {
 		AuthorizationRequest.authorizationCode()
-			.authorizeUri(null)
+			.authorizationUri(null)
 			.clientId(CLIENT_ID)
 			.redirectUri(REDIRECT_URI)
 			.scope(SCOPE)
@@ -59,7 +59,7 @@ public class AuthorizationRequestTest {
 	@Test(expected = IllegalArgumentException.class)
 	public void buildWhenClientIdIsNullThenThrowIllegalArgumentException() {
 		AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.clientId(null)
 			.redirectUri(REDIRECT_URI)
 			.scope(SCOPE)
@@ -70,7 +70,7 @@ public class AuthorizationRequestTest {
 	@Test(expected = IllegalArgumentException.class)
 	public void buildWhenClientIdNotSetThenThrowIllegalArgumentException() {
 		AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.redirectUri(REDIRECT_URI)
 			.scope(SCOPE)
 			.state(STATE)
@@ -81,7 +81,7 @@ public class AuthorizationRequestTest {
 	public void buildWhenGetResponseTypeIsCalledThenReturnCode() {
 		AuthorizationRequest authorizationRequest;
 		authorizationRequest = AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.clientId(CLIENT_ID)
 			.redirectUri(REDIRECT_URI)
 			.scope(SCOPE)
@@ -94,7 +94,7 @@ public class AuthorizationRequestTest {
 	@Test
 	public void buildWhenRedirectUriIsNullThenDoesNotThrowAnyException() {
 		assertThatCode(() -> AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.clientId(CLIENT_ID)
 			.redirectUri(null)
 			.scope(SCOPE)
@@ -105,7 +105,7 @@ public class AuthorizationRequestTest {
 	@Test
 	public void buildWhenRedirectUriNotSetThenDoesNotThrowAnyException() {
 		assertThatCode(() -> AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.clientId(CLIENT_ID)
 			.scope(SCOPE)
 			.state(STATE)
@@ -115,7 +115,7 @@ public class AuthorizationRequestTest {
 	@Test
 	public void buildWhenScopesIsNullThenDoesNotThrowAnyException() {
 		assertThatCode(() -> AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.clientId(CLIENT_ID)
 			.redirectUri(REDIRECT_URI)
 			.scope(null)
@@ -126,7 +126,7 @@ public class AuthorizationRequestTest {
 	@Test
 	public void buildWhenScopesNotSetThenDoesNotThrowAnyException() {
 		assertThatCode(() -> AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.clientId(CLIENT_ID)
 			.redirectUri(REDIRECT_URI)
 			.state(STATE)
@@ -136,7 +136,7 @@ public class AuthorizationRequestTest {
 	@Test
 	public void buildWhenStateIsNullThenDoesNotThrowAnyException() {
 		assertThatCode(() -> AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.clientId(CLIENT_ID)
 			.redirectUri(REDIRECT_URI)
 			.scope(SCOPE)
@@ -147,7 +147,7 @@ public class AuthorizationRequestTest {
 	@Test
 	public void buildWhenStateNotSetThenDoesNotThrowAnyException() {
 		assertThatCode(() -> AuthorizationRequest.authorizationCode()
-			.authorizeUri(AUTHORIZE_URI)
+			.authorizationUri(AUTHORIZE_URI)
 			.clientId(CLIENT_ID)
 			.redirectUri(REDIRECT_URI)
 			.scope(SCOPE)

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

@@ -114,7 +114,7 @@ public class DefaultOidcUserTests {
 	@Test
 	public void constructorWhenNameAttributeKeyClaimIsNotPresentThenThrowsException() {
 		this.thrown.expect(IllegalArgumentException.class);
-		this.thrown.expectMessage("Invalid nameAttributeKey: " + StandardClaim.NAME);
+		this.thrown.expectMessage("Missing attribute '" + StandardClaim.NAME + "' in attributes");
 
 		new DefaultOidcUser(TEST_AUTHORITIES, TEST_ID_TOKEN, TEST_USER_INFO, StandardClaim.NAME);
 	}