diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizationCodeAuthenticationProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizationCodeAuthenticationProvider.java index e5d6a3095f..b4b53811fd 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizationCodeAuthenticationProvider.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizationCodeAuthenticationProvider.java @@ -32,8 +32,11 @@ import org.springframework.security.oauth2.client.web.AuthorizationGrantTokenExc import org.springframework.security.oauth2.core.AccessToken; import org.springframework.security.oauth2.core.endpoint.TokenResponseAttributes; import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.security.oauth2.oidc.client.authentication.OidcClientAuthenticationToken; +import org.springframework.security.oauth2.oidc.client.authentication.OidcUserAuthenticationToken; import org.springframework.security.oauth2.oidc.core.IdToken; import org.springframework.security.oauth2.oidc.core.endpoint.OidcParameter; +import org.springframework.security.oauth2.oidc.core.user.OidcUser; import org.springframework.util.Assert; import java.util.Collection; @@ -68,6 +71,7 @@ import java.util.Collection; * @since 5.0 * @see AuthorizationCodeAuthenticationToken * @see OAuth2ClientAuthenticationToken + * @see OidcClientAuthenticationToken * @see OAuth2UserAuthenticationToken * @see AuthorizationGrantTokenExchanger * @see TokenResponseAttributes @@ -75,6 +79,7 @@ import java.util.Collection; * @see IdToken * @see OAuth2UserService * @see OAuth2User + * @see OidcUser * @see Section 4.1 Authorization Code Grant Flow * @see Section 3.1 OpenID Connect Authorization Code Flow * @see Section 4.1.3 Access Token Request @@ -128,8 +133,12 @@ public class AuthorizationCodeAuthenticationProvider implements AuthenticationPr idToken = new IdToken(jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaims()); } - OAuth2ClientAuthenticationToken oauth2ClientAuthentication = - new OAuth2ClientAuthenticationToken(clientRegistration, accessToken, idToken); + OAuth2ClientAuthenticationToken oauth2ClientAuthentication; + if (idToken != null) { + oauth2ClientAuthentication = new OidcClientAuthenticationToken(clientRegistration, accessToken, idToken); + } else { + oauth2ClientAuthentication = new OAuth2ClientAuthenticationToken(clientRegistration, accessToken); + } oauth2ClientAuthentication.setDetails(authorizationCodeAuthentication.getDetails()); OAuth2User user = this.userInfoService.loadUser(oauth2ClientAuthentication); @@ -137,8 +146,13 @@ public class AuthorizationCodeAuthenticationProvider implements AuthenticationPr Collection extends GrantedAuthority> authorities = this.authoritiesMapper.mapAuthorities(user.getAuthorities()); - OAuth2UserAuthenticationToken oauth2UserAuthentication = - new OAuth2UserAuthenticationToken(user, authorities, oauth2ClientAuthentication); + OAuth2UserAuthenticationToken oauth2UserAuthentication; + if (OidcUser.class.isAssignableFrom(user.getClass())) { + oauth2UserAuthentication = new OidcUserAuthenticationToken( + (OidcUser)user, authorities, (OidcClientAuthenticationToken)oauth2ClientAuthentication); + } else { + oauth2UserAuthentication = new OAuth2UserAuthenticationToken(user, authorities, oauth2ClientAuthentication); + } oauth2UserAuthentication.setDetails(oauth2ClientAuthentication.getDetails()); this.accessTokenRepository.saveSecurityToken(accessToken, oauth2UserAuthentication); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2ClientAuthenticationToken.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2ClientAuthenticationToken.java index 25a10f7574..6cf0dd8bc5 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2ClientAuthenticationToken.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2ClientAuthenticationToken.java @@ -21,7 +21,6 @@ import org.springframework.security.core.SpringSecurityCoreVersion; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AccessToken; -import org.springframework.security.oauth2.oidc.core.IdToken; import org.springframework.util.Assert; /** @@ -38,24 +37,19 @@ import org.springframework.util.Assert; * @since 5.0 * @see ClientRegistration * @see AccessToken - * @see IdToken * @see Section 5.1 Access Token Response */ public class OAuth2ClientAuthenticationToken extends AbstractAuthenticationToken { private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; private final ClientRegistration clientRegistration; private final AccessToken accessToken; - private final IdToken idToken; - - public OAuth2ClientAuthenticationToken(ClientRegistration clientRegistration, - AccessToken accessToken, IdToken idToken) { + public OAuth2ClientAuthenticationToken(ClientRegistration clientRegistration, AccessToken accessToken) { super(AuthorityUtils.NO_AUTHORITIES); Assert.notNull(clientRegistration, "clientRegistration cannot be null"); Assert.notNull(accessToken, "accessToken cannot be null"); this.clientRegistration = clientRegistration; this.accessToken = accessToken; - this.idToken = idToken; this.setAuthenticated(true); // The Client is authenticated by the Authorization Server } @@ -76,8 +70,4 @@ public class OAuth2ClientAuthenticationToken extends AbstractAuthenticationToken public AccessToken getAccessToken() { return this.accessToken; } - - public IdToken getIdToken() { - return this.idToken; - } } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2UserAuthenticationToken.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2UserAuthenticationToken.java index 75e2cc40ef..92ae66009c 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2UserAuthenticationToken.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2UserAuthenticationToken.java @@ -29,8 +29,8 @@ import java.util.Collection; * that represents an OAuth 2.0 User {@link Authentication}. * *
- * This {@link Authentication} associates an {@link OAuth2User} principal
- * to an "Authorized Client" identified in {@link #getClientAuthentication()}.
+ * This {@link Authentication} associates an {@link OAuth2User} principal to a
+ * {@link OAuth2ClientAuthenticationToken} which represents the "Authorized Client".
*
* @author Joe Grandja
* @since 5.0
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/user/web/nimbus/NimbusOAuth2UserService.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/user/web/nimbus/NimbusOAuth2UserService.java
index 47647831e4..7c7bf400a9 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/user/web/nimbus/NimbusOAuth2UserService.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/user/web/nimbus/NimbusOAuth2UserService.java
@@ -36,6 +36,7 @@ import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
+import org.springframework.security.oauth2.oidc.client.authentication.OidcClientAuthenticationToken;
import org.springframework.security.oauth2.oidc.core.UserInfo;
import org.springframework.security.oauth2.oidc.core.user.DefaultOidcUser;
import org.springframework.security.oauth2.oidc.core.user.OidcUser;
@@ -65,6 +66,7 @@ import java.util.Set;
* @author Joe Grandja
* @since 5.0
* @see OAuth2ClientAuthenticationToken
+ * @see OidcClientAuthenticationToken
* @see OAuth2User
* @see OidcUser
* @see UserInfo
@@ -86,14 +88,14 @@ public class NimbusOAuth2UserService implements OAuth2UserService {
if (this.getCustomUserTypes().containsKey(userInfoUri)) {
return this.loadCustomUser(token);
}
- if (token.getIdToken() != null) {
- return this.loadOidcUser(token);
+ if (OidcClientAuthenticationToken.class.isAssignableFrom(token.getClass())) {
+ return this.loadOidcUser((OidcClientAuthenticationToken)token);
}
return this.loadOAuth2User(token);
}
- protected OAuth2User loadOidcUser(OAuth2ClientAuthenticationToken token) throws OAuth2AuthenticationException {
+ protected OidcUser loadOidcUser(OidcClientAuthenticationToken token) throws OAuth2AuthenticationException {
// TODO Retrieving the UserInfo should be optional. Need to add the capability for opting in/out
Map
+ * A client is considered "authenticated",
+ * if it receives a successful response from the Token Endpoint.
+ * This {@link Authentication} associates the client identified in {@link #getClientRegistration()}
+ * to the {@link #getAccessToken()} granted by the resource owner along with the {@link #getIdToken()}
+ * containing Claims about the authentication of the End-User.
+ *
+ * @author Joe Grandja
+ * @since 5.0
+ * @see IdToken
+ * @see OAuth2ClientAuthenticationToken
+ * @see 3.1.3.3 Successful Token Response
+ */
+public class OidcClientAuthenticationToken extends OAuth2ClientAuthenticationToken {
+ private final IdToken idToken;
+
+ public OidcClientAuthenticationToken(ClientRegistration clientRegistration,
+ AccessToken accessToken, IdToken idToken) {
+
+ super(clientRegistration, accessToken);
+ Assert.notNull(idToken, "idToken cannot be null");
+ this.idToken = idToken;
+ }
+
+ public IdToken getIdToken() {
+ return this.idToken;
+ }
+}
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/oidc/client/authentication/OidcUserAuthenticationToken.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/oidc/client/authentication/OidcUserAuthenticationToken.java
new file mode 100644
index 0000000000..df98aca977
--- /dev/null
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/oidc/client/authentication/OidcUserAuthenticationToken.java
@@ -0,0 +1,45 @@
+/*
+ * 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.client.authentication;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.oauth2.client.authentication.OAuth2UserAuthenticationToken;
+import org.springframework.security.oauth2.oidc.core.user.OidcUser;
+
+import java.util.Collection;
+
+/**
+ * A {@link OAuth2UserAuthenticationToken} that represents an
+ * OpenID Connect 1.0 User {@link Authentication}.
+ *
+ *
+ * This {@link Authentication} associates an {@link OidcUser} principal to a
+ * {@link OidcClientAuthenticationToken} which represents the "Authorized Client".
+ *
+ * @author Joe Grandja
+ * @since 5.0
+ * @see OidcUser
+ * @see OidcClientAuthenticationToken
+ * @see OAuth2UserAuthenticationToken
+ */
+public class OidcUserAuthenticationToken extends OAuth2UserAuthenticationToken {
+
+ public OidcUserAuthenticationToken(OidcUser principal, Collection extends GrantedAuthority> authorities,
+ OidcClientAuthenticationToken clientAuthentication) {
+ super(principal, authorities, clientAuthentication);
+ }
+}