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

Commit 10e8fc4

Browse files
author
Richard Blaylock
committed
1264 - Add support for state token for stormpath_factor_challenge grant_type requests.
1 parent c8b112d commit 10e8fc4

File tree

8 files changed

+41
-7
lines changed

8 files changed

+41
-7
lines changed

api/src/main/java/com/stormpath/sdk/oauth/OAuthStormpathFactorChallengeGrantRequestAuthentication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424
public interface OAuthStormpathFactorChallengeGrantRequestAuthentication extends OAuthGrantRequestAuthentication {
2525

26+
String getState();
27+
2628
String getChallenge();
2729

2830
String getCode();

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,7 @@ class ApplicationIT extends ClientIT {
18901890
challenge = factor.createChallenge(challenge)
18911891

18921892
String bogusCode = "000000"
1893-
OAuthStormpathFactorChallengeGrantRequestAuthentication request = new DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication(challenge.href, bogusCode)
1893+
OAuthStormpathFactorChallengeGrantRequestAuthentication request = new DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication(null, challenge.href, bogusCode)
18941894

18951895
try {
18961896
Authenticators.OAUTH_STORMPATH_FACTOR_CHALLENGE_GRANT_REQUEST_AUTHENTICATOR.forApplication(app).authenticate(request)
@@ -1918,7 +1918,7 @@ class ApplicationIT extends ClientIT {
19181918

19191919
String validCode = calculateCurrentTOTP(new Base32().decode(factor.getSecret()))
19201920

1921-
OAuthStormpathFactorChallengeGrantRequestAuthentication request = new DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication(challenge.href, validCode)
1921+
OAuthStormpathFactorChallengeGrantRequestAuthentication request = new DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication(null, challenge.href, validCode)
19221922

19231923
def result = Authenticators.OAUTH_STORMPATH_FACTOR_CHALLENGE_GRANT_REQUEST_AUTHENTICATOR.forApplication(app).authenticate(request)
19241924
assertNotNull result.getAccessTokenHref()

extensions/servlet/src/main/java/com/stormpath/sdk/servlet/mvc/AccessTokenController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,11 @@ protected AccessTokenResult stormpathFactorChallengeAuthenticationRequest(HttpSe
319319

320320
try {
321321
Application app = getApplication(request);
322+
String state = request.getParameter("state");
322323
String challenge = request.getParameter("challenge");
323324
String code = request.getParameter("code");
324325
OAuthStormpathFactorChallengeGrantRequestAuthentication grantRequestAuthentication =
325-
new DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication(challenge, code);
326+
new DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication(state, challenge, code);
326327

327328
authenticationResult = Authenticators.OAUTH_STORMPATH_FACTOR_CHALLENGE_GRANT_REQUEST_AUTHENTICATOR
328329
.forApplication(app)

impl/src/main/java/com/stormpath/sdk/impl/ds/DefaultDataStore.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,13 @@ private String buildCanonicalBodyQueryParams(Map<String, Object> bodyData){
508508
Map<String, Object> treeMap = new TreeMap<String, Object>(bodyData);
509509
try {
510510
for (Map.Entry<String,Object> entry : treeMap.entrySet()) {
511+
Object value = entry.getValue();
512+
if (value != null) {
511513
if (builder.length() > 0) {
512514
builder.append(APPEND_PARAM_CHAR);
513515
}
514-
builder.append(String.format("%s=%s", URLEncoder.encode(entry.getKey(), "UTF-8"), URLEncoder.encode(entry.getValue().toString(), "UTF-8")));
516+
builder.append(String.format("%s=%s", URLEncoder.encode(entry.getKey(), "UTF-8"), URLEncoder.encode(value.toString(), "UTF-8")));
517+
}
515518
}
516519
} catch (UnsupportedEncodingException e){
517520
log.trace("Body content could not be properly encoded");

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@
2828
public class DefaultOAuthStormpathFactorChallengeGrantAuthenticationAttempt extends AbstractResource implements OAuthStormpathFactorChallengeGrantAuthenticationAttempt {
2929

3030
static final StringProperty GRANT_TYPE = new StringProperty("grant_type");
31+
static final StringProperty STATE = new StringProperty("state");
3132
static final StringProperty CHALLENGE = new StringProperty("challenge");
3233
static final StringProperty CODE = new StringProperty("code");
3334

34-
private static final Map<String, Property> PROPERTY_DESCRIPTORS = createPropertyDescriptorMap(GRANT_TYPE, CHALLENGE, CODE);
35+
private static final Map<String, Property> PROPERTY_DESCRIPTORS = createPropertyDescriptorMap(GRANT_TYPE, STATE, CHALLENGE, CODE);
3536

3637
public DefaultOAuthStormpathFactorChallengeGrantAuthenticationAttempt(InternalDataStore dataStore) {
3738
super(dataStore);
@@ -46,6 +47,11 @@ public void setGrantType(String grantType) {
4647
setProperty(GRANT_TYPE, grantType);
4748
}
4849

50+
@Override
51+
public void setState(String state) {
52+
setProperty(STATE, state);
53+
}
54+
4955
@Override
5056
public void setChallenge(String challenge) {
5157
setProperty(CHALLENGE, challenge);
@@ -60,6 +66,10 @@ public String getGrantType() {
6066
return getString(GRANT_TYPE);
6167
}
6268

69+
public String getState() {
70+
return getString(STATE);
71+
}
72+
6373
public String getChallenge() {
6474
return getString(CHALLENGE);
6575
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.stormpath.sdk.impl.oauth;
1717

1818
import com.stormpath.sdk.lang.Assert;
19+
import com.stormpath.sdk.lang.Strings;
1920
import com.stormpath.sdk.oauth.OAuthStormpathFactorChallengeGrantRequestAuthentication;
2021
import com.stormpath.sdk.oauth.OAuthStormpathSocialGrantRequestAuthentication;
2122

@@ -25,17 +26,26 @@
2526
public class DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication implements OAuthStormpathFactorChallengeGrantRequestAuthentication {
2627
private final static String grant_type = "stormpath_factor_challenge";
2728

29+
private String state;
2830
private String challenge;
2931
private String code;
3032

31-
public DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication(String challenge, String code) {
32-
Assert.hasText(challenge, "challenge cannot be null or empty.");
33+
public DefaultOAuthStormpathFactorChallengeGrantRequestAuthentication(String state, String challenge, String code) {
34+
if (!Strings.hasText(state)) {
35+
Assert.hasText(challenge, "either state or challenge must be provided.");
36+
}
3337
Assert.hasText(code, "code cannot be null or empty.");
3438

39+
this.state = state;
3540
this.challenge = challenge;
3641
this.code = code;
3742
}
3843

44+
@Override
45+
public String getState() {
46+
return state;
47+
}
48+
3949
@Override
4050
public String getChallenge() {
4151
return challenge;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public OAuthGrantRequestAuthenticationResult authenticate(OAuthRequestAuthentica
4545

4646
OAuthStormpathFactorChallengeGrantAuthenticationAttempt authenticationAttempt = new DefaultOAuthStormpathFactorChallengeGrantAuthenticationAttempt(dataStore);
4747
authenticationAttempt.setGrantType(authentication.getGrantType());
48+
authenticationAttempt.setState(authentication.getState());
4849
authenticationAttempt.setChallenge(authentication.getChallenge());
4950
authenticationAttempt.setCode(authentication.getCode());
5051

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ public interface OAuthStormpathFactorChallengeGrantAuthenticationAttempt extends
3636
*/
3737
void setChallenge(String challenge);
3838

39+
/**
40+
* Method used to set the state token referencing a challenge to be verified. Typically this token will have come
41+
* in response to a previous OAuth token request.
42+
* @param state the state token referencing the challenge to be verified.
43+
*/
44+
void setState(String state);
45+
3946
/**
4047
* Method used to set the code for the multifactor challenge.
4148
* @param code the code for the multifactor challenge.

0 commit comments

Comments
 (0)