diff --git a/api/src/main/java/com/stormpath/sdk/oauth/GrantAuthenticationToken.java b/api/src/main/java/com/stormpath/sdk/oauth/GrantAuthenticationToken.java index 3ad56ceebc..61059c3fa3 100644 --- a/api/src/main/java/com/stormpath/sdk/oauth/GrantAuthenticationToken.java +++ b/api/src/main/java/com/stormpath/sdk/oauth/GrantAuthenticationToken.java @@ -38,6 +38,14 @@ public interface GrantAuthenticationToken extends Resource { */ public String getRefreshToken(); + /** + * Returns the value denoting the id token of the response as a Json Web Token for certain requests. + * The details of id_token are described in the OpenID Connect spec. + * @return the String value denoting the id token of the response or null if there is no id token returned + * @since 1.4.0 + */ + public String getIdToken(); + /** * Returns the type of the token included in the response. * diff --git a/api/src/main/java/com/stormpath/sdk/oauth/OAuthGrantRequestAuthenticationResult.java b/api/src/main/java/com/stormpath/sdk/oauth/OAuthGrantRequestAuthenticationResult.java index 99db74b710..9a287e4872 100644 --- a/api/src/main/java/com/stormpath/sdk/oauth/OAuthGrantRequestAuthenticationResult.java +++ b/api/src/main/java/com/stormpath/sdk/oauth/OAuthGrantRequestAuthenticationResult.java @@ -37,6 +37,15 @@ public interface OAuthGrantRequestAuthenticationResult extends OAuthRequestAuthe */ AccessToken getAccessToken(); + + /** + * Returns the String that corresponds to the OpenID Connect id_token (if present) created during the Create Grant + * Authentication operation. + * @return the String representation of the OpenID Connect id_token + * @since 1.4.0 + */ + String getIdTokenString(); + /** * Returns the String that corresponds to the token created during the Refresh Grant Authentication operation. * @return the String representation of the Oauth refresh token diff --git a/api/src/main/java/com/stormpath/sdk/oauth/TokenResponse.java b/api/src/main/java/com/stormpath/sdk/oauth/TokenResponse.java index fb687899c8..95a537bf71 100644 --- a/api/src/main/java/com/stormpath/sdk/oauth/TokenResponse.java +++ b/api/src/main/java/com/stormpath/sdk/oauth/TokenResponse.java @@ -59,6 +59,13 @@ public interface TokenResponse { */ String getAccessToken(); + /** + * Returns the Id Token string that should be used by the client as defined in the OpenID Connect spec. + * @return the Id Token string that should be used by the client as defined in the OpenID Connect spec. + * @since 1.4.0 + */ + String getIdToken(); + /** * Returns the space separated collection of granted scopes. * diff --git a/extensions/oauth/src/main/java/com/stormpath/sdk/impl/oauth/authz/DefaultTokenResponse.java b/extensions/oauth/src/main/java/com/stormpath/sdk/impl/oauth/authz/DefaultTokenResponse.java index 0e9f424974..6d485eae99 100644 --- a/extensions/oauth/src/main/java/com/stormpath/sdk/impl/oauth/authz/DefaultTokenResponse.java +++ b/extensions/oauth/src/main/java/com/stormpath/sdk/impl/oauth/authz/DefaultTokenResponse.java @@ -27,11 +27,13 @@ public class DefaultTokenResponse implements TokenResponse { private final String applicationHref; private final OAuthResponse oAuthResponse; + private final String idToken; private DefaultTokenResponse(Builder builder) { accessToken = builder.accessToken; expiresIn = builder.expiresIn; refreshToken = builder.refreshToken; + idToken = builder.idToken; scope = builder.scope; tokenType = builder.tokenType; applicationHref = builder.applicationHref; @@ -52,6 +54,11 @@ public String getAccessToken() { return accessToken; } + @Override + public String getIdToken() { + return idToken; + } + @Override public String getScope() { return scope; @@ -93,6 +100,7 @@ public static class Builder { private String scope; private String tokenType; private String applicationHref; + private String idToken; private OAuthASResponse.OAuthTokenResponseBuilder tokenResponseBuilder; @@ -108,6 +116,11 @@ public Builder accessToken(String accessToken) { return this; } + public Builder idToken(String idToken) { + this.idToken = idToken; + return this; + } + public Builder scope(String scope) { this.scope = scope; tokenResponseBuilder.setScope(scope); diff --git a/extensions/servlet/src/main/java/com/stormpath/sdk/servlet/filter/oauth/DefaultAccessTokenResultFactory.java b/extensions/servlet/src/main/java/com/stormpath/sdk/servlet/filter/oauth/DefaultAccessTokenResultFactory.java index 8d90cecf16..53f53754e0 100644 --- a/extensions/servlet/src/main/java/com/stormpath/sdk/servlet/filter/oauth/DefaultAccessTokenResultFactory.java +++ b/extensions/servlet/src/main/java/com/stormpath/sdk/servlet/filter/oauth/DefaultAccessTokenResultFactory.java @@ -48,6 +48,7 @@ public AccessTokenResult createAccessTokenResult(HttpServletRequest request, Htt DefaultTokenResponse.tokenType(TokenType.BEARER) .accessToken(result.getAccessTokenString()) .refreshToken(result.getRefreshTokenString()) + .idToken(result.getIdTokenString()) .applicationHref(application.getHref()) .expiresIn(String.valueOf(result.getExpiresIn())).build(); return new PasswordGrantAccessTokenResult(result.getAccessToken().getAccount(), tokenResponse); diff --git a/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationToken.java b/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationToken.java index b62cb7a187..007bdf7301 100644 --- a/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationToken.java +++ b/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationToken.java @@ -34,12 +34,12 @@ public class DefaultGrantAuthenticationToken extends AbstractInstanceResource implements GrantAuthenticationToken { static final StringProperty ACCESS_TOKEN = new StringProperty("access_token"); + static final StringProperty ID_TOKEN = new StringProperty("id_token"); static final StringProperty REFRESH_TOKEN = new StringProperty("refresh_token"); static final StringProperty TOKEN_TYPE = new StringProperty("token_type"); static final StringProperty EXPIRES_IN = new StringProperty("expires_in"); static final StringProperty ACCESS_TOKEN_HREF = new StringProperty("stormpath_access_token_href"); - - static final Map PROPERTY_DESCRIPTORS = createPropertyDescriptorMap(ACCESS_TOKEN, REFRESH_TOKEN, EXPIRES_IN, TOKEN_TYPE, ACCESS_TOKEN_HREF); + static final Map PROPERTY_DESCRIPTORS = createPropertyDescriptorMap(ACCESS_TOKEN, REFRESH_TOKEN, ID_TOKEN, EXPIRES_IN, TOKEN_TYPE, ACCESS_TOKEN_HREF); public DefaultGrantAuthenticationToken(InternalDataStore dataStore) { super(dataStore); @@ -62,6 +62,10 @@ public String getRefreshToken() { return getString(REFRESH_TOKEN); } + public String getIdToken() { + return getString(ID_TOKEN); + } + public String getTokenType() { return getString(TOKEN_TYPE); } @@ -75,7 +79,7 @@ public String getAccessTokenHref() { } public AccessToken getAsAccessToken(){ - Map props = new LinkedHashMap(1); + Map props = new LinkedHashMap<>(1); props.put("href", this.getAccessTokenHref()); return getDataStore().instantiate(AccessToken.class, props); } @@ -89,7 +93,7 @@ public RefreshToken getAsRefreshToken() { } Jws jws = AbstractBaseOAuthToken.parseJws(refreshToken, getDataStore()); - Map props = new LinkedHashMap(1); + Map props = new LinkedHashMap<>(1); String refreshTokenID = jws.getBody().getId(); props.put("href", getDataStore().getBaseUrl() + "/refreshTokens/" + refreshTokenID); return getDataStore().instantiate(RefreshToken.class, props); diff --git a/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthClientCredentialsGrantRequestAuthenticationResultBuilder.java b/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthClientCredentialsGrantRequestAuthenticationResultBuilder.java index 1a96f26a92..1d15c2e24f 100644 --- a/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthClientCredentialsGrantRequestAuthenticationResultBuilder.java +++ b/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthClientCredentialsGrantRequestAuthenticationResultBuilder.java @@ -18,6 +18,7 @@ public DefaultOAuthGrantRequestAuthenticationResult build() { this.accessToken = grantAuthenticationToken.getAsAccessToken(); this.accessTokenString = grantAuthenticationToken.getAccessToken(); + this.idTokenString = grantAuthenticationToken.getIdToken(); this.accessTokenHref = grantAuthenticationToken.getAccessTokenHref(); this.tokenType = grantAuthenticationToken.getTokenType(); this.expiresIn = Integer.parseInt(grantAuthenticationToken.getExpiresIn()); diff --git a/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthGrantRequestAuthenticationResult.java b/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthGrantRequestAuthenticationResult.java index 913e9cf80d..bb93aa52ee 100644 --- a/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthGrantRequestAuthenticationResult.java +++ b/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthGrantRequestAuthenticationResult.java @@ -16,7 +16,9 @@ package com.stormpath.sdk.impl.oauth; import com.stormpath.sdk.lang.Classes; -import com.stormpath.sdk.oauth.*; +import com.stormpath.sdk.oauth.AccessToken; +import com.stormpath.sdk.oauth.OAuthGrantRequestAuthenticationResult; +import com.stormpath.sdk.oauth.RefreshToken; /** * @since 1.0.RC7 @@ -27,6 +29,8 @@ public class DefaultOAuthGrantRequestAuthenticationResult implements OAuthGrantR private final String accessTokenString; + private final String idTokenString; + private final RefreshToken refreshToken; private final String refreshTokenString; @@ -40,6 +44,7 @@ public class DefaultOAuthGrantRequestAuthenticationResult implements OAuthGrantR public DefaultOAuthGrantRequestAuthenticationResult(DefaultOAuthGrantRequestAuthenticationResultBuilder builder) { this.accessToken = builder.getAccessToken(); this.accessTokenString = builder.getAccessTokenString(); + this.idTokenString = builder.getIdTokenString(); this.refreshToken = builder.getRefreshToken(); this.refreshTokenString = builder.getRefreshTokenString(); this.accessTokenHref = builder.getAccessTokenHref(); @@ -51,6 +56,11 @@ public AccessToken getAccessToken() { return accessToken; } + @Override + public String getIdTokenString() { + return idTokenString; + } + public String getRefreshTokenString() { return refreshTokenString; } diff --git a/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthGrantRequestAuthenticationResultBuilder.java b/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthGrantRequestAuthenticationResultBuilder.java index 534d132abf..d47d245f45 100644 --- a/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthGrantRequestAuthenticationResultBuilder.java +++ b/impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultOAuthGrantRequestAuthenticationResultBuilder.java @@ -33,6 +33,8 @@ public class DefaultOAuthGrantRequestAuthenticationResultBuilder implements OAut protected String refreshTokenString; + protected String idTokenString; + protected String accessTokenHref; protected String tokenType; @@ -54,6 +56,10 @@ public String getAccessTokenString() { return accessTokenString; } + public String getIdTokenString() { + return idTokenString; + } + public RefreshToken getRefreshToken() { return refreshToken; } @@ -80,6 +86,7 @@ public DefaultOAuthGrantRequestAuthenticationResult build() { this.accessToken = grantAuthenticationToken.getAsAccessToken(); this.accessTokenString = grantAuthenticationToken.getAccessToken(); + this.idTokenString = grantAuthenticationToken.getIdToken(); this.refreshTokenString = grantAuthenticationToken.getRefreshToken(); this.accessTokenHref = grantAuthenticationToken.getAccessTokenHref(); this.tokenType = grantAuthenticationToken.getTokenType(); diff --git a/impl/src/test/groovy/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationTokenTest.groovy b/impl/src/test/groovy/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationTokenTest.groovy index e50ae40e77..06bdd562c6 100644 --- a/impl/src/test/groovy/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationTokenTest.groovy +++ b/impl/src/test/groovy/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationTokenTest.groovy @@ -16,12 +16,12 @@ package com.stormpath.sdk.impl.oauth import com.stormpath.sdk.impl.ds.InternalDataStore -import com.stormpath.sdk.impl.resource.DateProperty import com.stormpath.sdk.impl.resource.StringProperty import org.testng.annotations.Test -import static org.easymock.EasyMock.* -import static org.testng.Assert.* +import static org.easymock.EasyMock.createStrictMock +import static org.testng.Assert.assertEquals +import static org.testng.Assert.assertTrue /** * Test for DefaultGrantAuthenticationToken class @@ -36,10 +36,11 @@ class DefaultGrantAuthenticationTokenTest { def propertyDescriptors = defaultGrantAuthenticationToken.getPropertyDescriptors() - assertEquals(propertyDescriptors.size(), 5) + assertEquals(propertyDescriptors.size(), 6) assertTrue(propertyDescriptors.get("access_token") instanceof StringProperty) assertTrue(propertyDescriptors.get("refresh_token") instanceof StringProperty) + assertTrue(propertyDescriptors.get("id_token") instanceof StringProperty) assertTrue(propertyDescriptors.get("token_type") instanceof StringProperty) assertTrue(propertyDescriptors.get("expires_in") instanceof StringProperty) assertTrue(propertyDescriptors.get("stormpath_access_token_href") instanceof StringProperty) @@ -51,6 +52,7 @@ class DefaultGrantAuthenticationTokenTest { def properties = [ access_token: "32J45K565JK3N4K5JN3K4QVMwOFFIRlhNTzdGNTY4Ukc2IiwiYWxnIjoiSFMyNT", refresh_token: "eyJraWQiOiI2UDVKTjRTQVMwOFFIRlhNTzdGNTY4Ukc2IiwiYWxnIjoiSFMyNT", + id_token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9", token_type: "Bearer", stormpath_access_token_href: "https://api.stormpath.com/v1/accessTokens/5hFj6FUwNb28OQrp93phPP", expires_in: "3600", @@ -61,6 +63,7 @@ class DefaultGrantAuthenticationTokenTest { assertEquals(defaultGrantAuthenticationToken.getAccessToken(), properties.access_token) assertEquals(defaultGrantAuthenticationToken.getRefreshToken(), properties.refresh_token) + assertEquals(defaultGrantAuthenticationToken.getIdToken(), properties.id_token) assertEquals(defaultGrantAuthenticationToken.getExpiresIn(), properties.expires_in) assertEquals(defaultGrantAuthenticationToken.getTokenType(), properties.token_type) assertEquals(defaultGrantAuthenticationToken.getAccessTokenHref(), properties.stormpath_access_token_href)