Skip to content
This repository was archived by the owner on Dec 12, 2018. It is now read-only.

Commit 803f12d

Browse files
author
Jose Luis Barrueta
authored
Merge pull request #1134 from stormpath/Issue-1132
Issue 1132
2 parents 185d3dc + 5e35d87 commit 803f12d

6 files changed

Lines changed: 101 additions & 6 deletions

File tree

api/src/main/java/com/stormpath/sdk/lang/Strings.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.stormpath.sdk.lang;
1717

1818
import java.nio.charset.Charset;
19+
import java.nio.charset.StandardCharsets;
1920
import java.util.ArrayList;
2021
import java.util.Arrays;
2122
import java.util.Collection;
@@ -1264,4 +1265,34 @@ public static String arrayToCommaDelimitedString(Object[] arr) {
12641265
return arrayToDelimitedString(arr, ",");
12651266
}
12661267

1268+
/**
1269+
* Calls {@link String#getBytes(Charset)}
1270+
*
1271+
* @param string The string to encode (if null, return null).
1272+
* @param charset The {@link Charset} to encode the <code>String</code>
1273+
* @return the encoded bytes
1274+
* @since 1.2.1
1275+
*/
1276+
private static byte[] getBytes(final String string, final Charset charset) {
1277+
if (string == null) {
1278+
return null;
1279+
}
1280+
return string.getBytes(charset);
1281+
}
1282+
1283+
/**
1284+
* Encodes the given string into a sequence of bytes using the UTF-8 charset, storing the result into a new byte
1285+
* array.
1286+
*
1287+
* @param string the String to encode, may be <code>null</code>
1288+
* @return encoded bytes, or <code>null</code> if the input string was <code>null</code>
1289+
* @throws NullPointerException Thrown if {@link StandardCharsets#UTF_8} is not initialized, which should never happen since it is
1290+
* required by the Java platform specification.
1291+
* @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
1292+
* @since 1.2.1
1293+
*/
1294+
public static byte[] getBytesUtf8(final String string) {
1295+
return getBytes(string, StandardCharsets.UTF_8);
1296+
}
1297+
12671298
}

ci/before_install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export IS_RELEASE="$([ ${RELEASE_VERSION/SNAPSHOT} == $RELEASE_VERSION ] && [ $T
1414
export BUILD_DOCS="$([ $TRAVIS_JDK_VERSION == 'oraclejdk8' ] && echo 'true')"
1515
export RUN_ITS="$([ $TRAVIS_JDK_VERSION == 'openjdk7' ] && echo 'true')"
1616
#Install Maven 3.3.9 since Travis uses 3.2 by default
17-
wget https://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip
17+
wget http://mirror.cc.columbia.edu/pub/software/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip
1818
unzip -qq apache-maven-3.3.9-bin.zip
1919
export M2_HOME=$PWD/apache-maven-3.3.9
2020
export PATH=$M2_HOME/bin:$PATH

extensions/httpclient/src/test/groovy/com/stormpath/sdk/impl/application/webconfig/WebConfigurationIT.groovy

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,18 @@ import com.stormpath.sdk.application.webconfig.MeConfig
2727
import com.stormpath.sdk.application.webconfig.MeExpansionConfig
2828
import com.stormpath.sdk.application.webconfig.Oauth2Config
2929
import com.stormpath.sdk.application.webconfig.VerifyEmailConfig
30+
import com.stormpath.sdk.cache.Caches
3031
import com.stormpath.sdk.client.Client
3132
import com.stormpath.sdk.client.ClientIT
33+
import com.stormpath.sdk.client.Clients
3234
import com.stormpath.sdk.directory.Directory
35+
import com.stormpath.sdk.oauth.AccessToken
36+
import com.stormpath.sdk.oauth.Authenticators
37+
import com.stormpath.sdk.oauth.OAuthBearerRequestAuthentication
38+
import com.stormpath.sdk.oauth.OAuthPasswordGrantRequestAuthentication
39+
import com.stormpath.sdk.oauth.OAuthRequestAuthenticator
40+
import com.stormpath.sdk.oauth.OAuthRequests
41+
import com.stormpath.sdk.oauth.RefreshToken
3342
import org.testng.annotations.Test
3443

3544
import static org.testng.Assert.*
@@ -185,6 +194,42 @@ class WebConfigurationIT extends ClientIT {
185194
}
186195
}
187196

197+
@Test
198+
void testGetAccessTokenSignedWithDifferentKey() {
199+
200+
def app = createTempApp()
201+
202+
def account = createTestAccount(app)
203+
204+
OAuthPasswordGrantRequestAuthentication grantRequest = OAuthRequests.OAUTH_PASSWORD_GRANT_REQUEST.builder()
205+
.setLogin(account.email).setPassword("Changeme1!").build()
206+
207+
OAuthRequestAuthenticator authenticator = Authenticators.OAUTH_PASSWORD_GRANT_REQUEST_AUTHENTICATOR.forApplication(app)
208+
209+
def accessTokenResult = authenticator.authenticate(grantRequest)
210+
211+
def webConfigApiKey = app.getWebConfig().getSigningApiKey()
212+
213+
def client = Clients.builder().setBaseUrl(baseUrl).setCacheManager(Caches.newDisabledCacheManager()).setApiKey(webConfigApiKey).build()
214+
215+
def newClientApp = client.getResource(app.href, Application)
216+
217+
// Authenticate token against Stormpath
218+
OAuthBearerRequestAuthentication authRequest = OAuthRequests.OAUTH_BEARER_REQUEST.builder().setJwt(accessTokenResult.getAccessTokenString()).build()
219+
def authResultRemote = Authenticators.OAUTH_BEARER_REQUEST_AUTHENTICATOR.forApplication(newClientApp).authenticate(authRequest)
220+
221+
assertEquals authResultRemote.getApplication().getHref(), app.href
222+
assertEquals authResultRemote.getAccount().getHref(), account.href
223+
224+
def accessToken = client.getResource(accessTokenResult.accessTokenHref, AccessToken)
225+
226+
assertNotNull accessToken
227+
228+
def refreshToken = client.getResource(accessTokenResult.refreshToken.href, RefreshToken)
229+
230+
assertNotNull refreshToken
231+
}
232+
188233
ApiKey createTmpApiKey(Application application) {
189234
def directory = client.instantiate(Directory)
190235
directory.setName(uniquify("Admins"))

impl/src/main/java/com/stormpath/sdk/impl/oauth/AbstractBaseOAuthToken.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
import com.stormpath.sdk.tenant.Tenant;
2020
import io.jsonwebtoken.Claims;
2121
import io.jsonwebtoken.Jws;
22+
import io.jsonwebtoken.JwsHeader;
2223
import io.jsonwebtoken.Jwts;
24+
import io.jsonwebtoken.SigningKeyResolverAdapter;
2325

2426
import java.util.Date;
2527
import java.util.Map;
@@ -102,8 +104,26 @@ public void revoke() {
102104
OAuthTokenRevocators.OAUTH_TOKEN_REVOCATOR.forApplication(getApplication()).revoke(revocationRequest);
103105
}
104106

105-
protected static Jws<Claims> parseJws(String token, ApiKey apiKey) {
106-
return Jwts.parser().setSigningKey(apiKey.getSecret().getBytes(Strings.UTF_8)).parseClaimsJws(token);
107+
/**
108+
* @since 1.2.1
109+
*/
110+
protected static Jws<Claims> parseJws(String token, final InternalDataStore dataStore) {
111+
112+
final ApiKey clientApiKey = dataStore.getApiKey();
113+
114+
return Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
115+
@Override
116+
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
117+
String keyId = header.getKeyId();
118+
119+
if (Strings.hasText(keyId) && !clientApiKey.getId().equals(keyId)) {
120+
String url = dataStore.getBaseUrl() + "/apiKeys/" + keyId;
121+
ApiKey apiKey = dataStore.getResource(url, ApiKey.class);
122+
return Strings.getBytesUtf8(apiKey.getSecret());
123+
}
124+
return Strings.getBytesUtf8(clientApiKey.getSecret());
125+
}
126+
}).parseClaimsJws(token);
107127
}
108128

109129
protected abstract TokenTypeHint getTokenTypeHint();

impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultAccessToken.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ private void ensureAccessToken() {
4747
if(isMaterialized()) {
4848
try {
4949

50-
ApiKey apiKey = getDataStore().getApiKey();
51-
JwsHeader header = AbstractBaseOAuthToken.parseJws(getString(JWT), apiKey).getHeader();
50+
JwsHeader header = AbstractBaseOAuthToken.parseJws(getString(JWT), getDataStore()).getHeader();
5251

5352
String tokenType = (String) header.get("stt");
5453
Assert.isTrue(tokenType.equals("access"));

impl/src/main/java/com/stormpath/sdk/impl/oauth/DefaultGrantAuthenticationToken.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public RefreshToken getAsRefreshToken() {
8888
return null;
8989
}
9090

91-
Jws<Claims> jws = AbstractBaseOAuthToken.parseJws(refreshToken, getDataStore().getApiKey());
91+
Jws<Claims> jws = AbstractBaseOAuthToken.parseJws(refreshToken, getDataStore());
9292
Map<String, Object> props = new LinkedHashMap<String, Object>(1);
9393
String refreshTokenID = jws.getBody().getId();
9494
props.put("href", getDataStore().getBaseUrl() + "/refreshTokens/" + refreshTokenID);

0 commit comments

Comments
 (0)