Skip to content

Commit

Permalink
extract class to separate file and getters/setters
Browse files Browse the repository at this point in the history
  • Loading branch information
lbalmaceda committed Dec 4, 2019
1 parent 8931616 commit 2cdcf22
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.auth0.android.provider;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.util.Date;

class IdTokenVerificationOptions {
private final String issuer;
private final String audience;
private final SignatureVerifier verifier;
private String nonce;
private Integer maxAge;
private Integer clockSkew;
private Date clock;

IdTokenVerificationOptions(@NonNull String issuer, @NonNull String audience, @NonNull SignatureVerifier verifier) {
this.issuer = issuer;
this.audience = audience;
this.verifier = verifier;
}

void setNonce(@Nullable String nonce) {
this.nonce = nonce;
}

void setMaxAge(@Nullable Integer maxAge) {
this.maxAge = maxAge;
}

void setClockSkew(@Nullable Integer clockSkew) {
this.clockSkew = clockSkew;
}

void setClock(@Nullable Date now) {
this.clock = now;
}

@NonNull
String getIssuer() {
return issuer;
}

@NonNull
String getAudience() {
return audience;
}

@NonNull
SignatureVerifier getSignatureVerifier() {
return verifier;
}

@Nullable
String getNonce() {
return nonce;
}

@Nullable
Integer getMaxAge() {
return maxAge;
}

@Nullable
Integer getClockSkew() {
return clockSkew;
}

@Nullable
Date getClock() {
return clock;
}
}
62 changes: 15 additions & 47 deletions auth0/src/main/java/com/auth0/android/provider/IdTokenVerifier.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.auth0.android.provider;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.auth0.android.jwt.JWT;

Expand All @@ -26,15 +25,15 @@ class IdTokenVerifier {
* @param verifyOptions the verification options, like audience, issuer, algorithm.
* @throws TokenValidationException If the ID Token is null, its signing algorithm not supported, its signature invalid or one of its claim invalid.
*/
void verify(@NonNull JWT token, @NonNull Options verifyOptions) throws TokenValidationException {
verifyOptions.verifier.verifySignature(token);
void verify(@NonNull JWT token, @NonNull IdTokenVerificationOptions verifyOptions) throws TokenValidationException {
verifyOptions.getSignatureVerifier().verifySignature(token);

if (isEmpty(token.getIssuer())) {
throw new TokenValidationException("Issuer (iss) claim must be a string present in the ID token");
}
//noinspection ConstantConditions
if (!token.getIssuer().equals(verifyOptions.issuer)) {
throw new TokenValidationException(String.format("Issuer (iss) claim mismatch in the ID token, expected \"%s\", found \"%s\"", verifyOptions.issuer, token.getIssuer()));
if (!token.getIssuer().equals(verifyOptions.getIssuer())) {
throw new TokenValidationException(String.format("Issuer (iss) claim mismatch in the ID token, expected \"%s\", found \"%s\"", verifyOptions.getIssuer(), token.getIssuer()));
}

if (isEmpty(token.getSubject())) {
Expand All @@ -45,13 +44,13 @@ void verify(@NonNull JWT token, @NonNull Options verifyOptions) throws TokenVali
if (audience == null) {
throw new TokenValidationException("Audience (aud) claim must be a string or array of strings present in the ID token");
}
if (!audience.contains(verifyOptions.audience)) {
throw new TokenValidationException(String.format("Audience (aud) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", verifyOptions.audience, token.getAudience()));
if (!audience.contains(verifyOptions.getAudience())) {
throw new TokenValidationException(String.format("Audience (aud) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", verifyOptions.getAudience(), token.getAudience()));
}

final Calendar cal = Calendar.getInstance();
final Date now = verifyOptions.clock != null ? verifyOptions.clock : cal.getTime();
final int clockSkew = verifyOptions.clockSkew != null ? verifyOptions.clockSkew : DEFAULT_CLOCK_SKEW;
final Date now = verifyOptions.getClock() != null ? verifyOptions.getClock() : cal.getTime();
final int clockSkew = verifyOptions.getClockSkew() != null ? verifyOptions.getClockSkew() : DEFAULT_CLOCK_SKEW;

if (token.getExpiresAt() == null) {
throw new TokenValidationException("Expiration Time (exp) claim must be a number present in the ID token");
Expand All @@ -78,13 +77,13 @@ void verify(@NonNull JWT token, @NonNull Options verifyOptions) throws TokenVali
}


if (verifyOptions.nonce != null) {
if (verifyOptions.getNonce() != null) {
String nonceClaim = token.getClaim(NONCE_CLAIM).asString();
if (isEmpty(nonceClaim)) {
throw new TokenValidationException("Nonce (nonce) claim must be a string present in the ID token");
}
if (!verifyOptions.nonce.equals(nonceClaim)) {
throw new TokenValidationException(String.format("Nonce (nonce) claim mismatch in the ID token; expected \"%s\", found \"%s\"", verifyOptions.nonce, nonceClaim));
if (!verifyOptions.getNonce().equals(nonceClaim)) {
throw new TokenValidationException(String.format("Nonce (nonce) claim mismatch in the ID token; expected \"%s\", found \"%s\"", verifyOptions.getNonce(), nonceClaim));
}
}

Expand All @@ -93,19 +92,19 @@ void verify(@NonNull JWT token, @NonNull Options verifyOptions) throws TokenVali
if (isEmpty(azpClaim)) {
throw new TokenValidationException("Authorized Party (azp) claim must be a string present in the ID token when Audience (aud) claim has multiple values");
}
if (!verifyOptions.audience.equals(azpClaim)) {
throw new TokenValidationException(String.format("Authorized Party (azp) claim mismatch in the ID token; expected \"%s\", found \"%s\"", verifyOptions.audience, azpClaim));
if (!verifyOptions.getAudience().equals(azpClaim)) {
throw new TokenValidationException(String.format("Authorized Party (azp) claim mismatch in the ID token; expected \"%s\", found \"%s\"", verifyOptions.getAudience(), azpClaim));
}
}

if (verifyOptions.maxAge != null) {
if (verifyOptions.getMaxAge() != null) {
Date authTime = token.getClaim(AUTH_TIME_CLAIM).asDate();
if (authTime == null) {
throw new TokenValidationException("Authentication Time (auth_time) claim must be a number present in the ID token when Max Age (max_age) is specified");
}

cal.setTime(authTime);
cal.add(Calendar.SECOND, verifyOptions.maxAge);
cal.add(Calendar.SECOND, verifyOptions.getMaxAge());
cal.add(Calendar.SECOND, clockSkew);
Date authTimeDate = cal.getTime();

Expand All @@ -115,35 +114,4 @@ void verify(@NonNull JWT token, @NonNull Options verifyOptions) throws TokenVali
}
}

static class Options {
final String issuer;
final String audience;
final SignatureVerifier verifier;
String nonce;
private Integer maxAge;
Integer clockSkew;
Date clock;

Options(@NonNull String issuer, @NonNull String audience, @NonNull SignatureVerifier verifier) {
this.issuer = issuer;
this.audience = audience;
this.verifier = verifier;
}

void setNonce(@Nullable String nonce) {
this.nonce = nonce;
}

void setMaxAge(@Nullable Integer maxAge) {
this.maxAge = maxAge;
}

void setClockSkew(@Nullable Integer clockSkew) {
this.clockSkew = clockSkew;
}

void setClock(@Nullable Date now) {
this.clock = now;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ boolean resume(AuthorizeResult result) {

final Date expiresAt = !values.containsKey(KEY_EXPIRES_IN) ? null : new Date(getCurrentTimeInMillis() + Long.valueOf(values.get(KEY_EXPIRES_IN)) * 1000);
boolean frontChannelIdTokenExpected = parameters.containsKey(KEY_RESPONSE_TYPE) && parameters.get(KEY_RESPONSE_TYPE).contains(RESPONSE_TYPE_ID_TOKEN);
final Credentials frontChannelCredentials = new Credentials(frontChannelIdTokenExpected?values.get(KEY_ID_TOKEN) : null, values.get(KEY_ACCESS_TOKEN), values.get(KEY_TOKEN_TYPE), null, expiresAt, values.get(KEY_SCOPE));
final Credentials frontChannelCredentials = new Credentials(frontChannelIdTokenExpected ? values.get(KEY_ID_TOKEN) : null, values.get(KEY_ACCESS_TOKEN), values.get(KEY_TOKEN_TYPE), null, expiresAt, values.get(KEY_SCOPE));

if (frontChannelIdTokenExpected) {
//Must be response_type=id_token (or additional values)
Expand Down Expand Up @@ -225,7 +225,7 @@ public void onFailure(TokenValidationException error) {

@Override
public void onSuccess(SignatureVerifier signatureVerifier) {
IdTokenVerifier.Options options = new IdTokenVerifier.Options(apiClient.getBaseURL(), apiClient.getClientId(), signatureVerifier);
IdTokenVerificationOptions options = new IdTokenVerificationOptions(apiClient.getBaseURL(), apiClient.getClientId(), signatureVerifier);
String maxAge = parameters.get(KEY_MAX_AGE);
if (!TextUtils.isEmpty(maxAge)) {
//noinspection ConstantConditions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ public Builder withNonce(@NonNull String nonce) {
* @return the current builder instance
*/
public Builder withMaxAge(@NonNull Integer maxAge) {
//TODO: This is set by the user. Should that be directly a string?
this.values.put(KEY_MAX_AGE, String.valueOf(maxAge));
return this;
}
Expand Down

0 comments on commit 2cdcf22

Please sign in to comment.