Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple issuers #246 #288

Merged
merged 10 commits into from
Mar 11, 2019
17 changes: 11 additions & 6 deletions lib/src/main/java/com/auth0/jwt/JWTVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ public static class BaseVerification implements Verification {
/**
* Require a specific Issuer ("iss") claim.
*
* @param issuer the required Issuer value
* @param issuer the required Issuer value. If multiple values are given, the claim must at least match one of them
* @return this same Verification instance.
*/
@Override
public Verification withIssuer(String issuer) {
requireClaim(PublicClaims.ISSUER, issuer);
public Verification withIssuer(String... issuer) {
lbalmaceda marked this conversation as resolved.
Show resolved Hide resolved
requireClaim(PublicClaims.ISSUER, issuer == null ? null : Arrays.asList(issuer));
return this;
}

Expand All @@ -90,7 +90,7 @@ public Verification withSubject(String subject) {
*/
@Override
public Verification withAudience(String... audience) {
requireClaim(PublicClaims.AUDIENCE, Arrays.asList(audience));
requireClaim(PublicClaims.AUDIENCE, audience == null ? null : Arrays.asList(audience));
return this;
}

Expand Down Expand Up @@ -398,7 +398,6 @@ private void verifyClaims(DecodedJWT jwt, Map<String, Object> claims) throws Tok
for (Map.Entry<String, Object> entry : claims.entrySet()) {
switch (entry.getKey()) {
case PublicClaims.AUDIENCE:
//noinspection unchecked
assertValidAudienceClaim(jwt.getAudience(), (List<String>) entry.getValue());
break;
case PublicClaims.EXPIRES_AT:
Expand All @@ -411,7 +410,7 @@ private void verifyClaims(DecodedJWT jwt, Map<String, Object> claims) throws Tok
assertValidDateClaim(jwt.getNotBefore(), (Long) entry.getValue(), false);
break;
case PublicClaims.ISSUER:
assertValidStringClaim(entry.getKey(), jwt.getIssuer(), (String) entry.getValue());
assertValidIssuerClaim(jwt.getIssuer(), (List<String>) entry.getValue());
break;
case PublicClaims.JWT_ID:
assertValidStringClaim(entry.getKey(), jwt.getId(), (String) entry.getValue());
Expand Down Expand Up @@ -486,4 +485,10 @@ private void assertValidAudienceClaim(List<String> audience, List<String> value)
throw new InvalidClaimException("The Claim 'aud' value doesn't contain the required audience.");
}
}

private void assertValidIssuerClaim(String issuer, List<String> value) {
if (issuer == null || !value.contains(issuer)) {
throw new InvalidClaimException("The Claim 'iss' value doesn't match the required issuer.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.Date;

public interface Verification {
Verification withIssuer(String issuer);
Verification withIssuer(String... issuer);

Verification withSubject(String subject);

Expand Down
38 changes: 37 additions & 1 deletion lib/src/test/java/com/auth0/jwt/JWTVerifierTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,41 @@ public void shouldValidateIssuer() throws Exception {
assertThat(jwt, is(notNullValue()));
}

@Test
public void shouldValidateMultipleIssuers() {
String auth0Token = "eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mZ0m_N1J4PgeqWmi903JuUoDRZDBPB7HwkS4nVyWH1M";
String otherIssuertoken = "eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJvdGhlcklzc3VlciJ9.k4BCOJJl-c0_Y-49VD_mtt-u0QABKSV5i3W-RKc74co";
JWTVerifier verifier = JWTVerifier.init(Algorithm.HMAC256("secret"))
.withIssuer("otherIssuer", "auth0")
.build();

itdevelopmentapps marked this conversation as resolved.
Show resolved Hide resolved
assertThat(verifier.verify(auth0Token), is(notNullValue()));
assertThat(verifier.verify(otherIssuertoken), is(notNullValue()));
}

@Test
public void shouldThrowOnInvalidIssuer() throws Exception {
exception.expect(InvalidClaimException.class);
exception.expectMessage("The Claim 'iss' value doesn't match the required one.");
exception.expectMessage("The Claim 'iss' value doesn't match the required issuer.");
String token = "eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mZ0m_N1J4PgeqWmi903JuUoDRZDBPB7HwkS4nVyWH1M";
JWTVerifier.init(Algorithm.HMAC256("secret"))
.withIssuer("invalid")
.build()
.verify(token);
}

@Test
public void shouldThrowOnNullIssuer() throws Exception {
exception.expect(InvalidClaimException.class);
exception.expectMessage("The Claim 'iss' value doesn't match the required issuer.");

String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.t-IDcSemACt8x4iTMCda8Yhe3iZaWbvV5XKSTbuAn0M";
JWTVerifier.init(Algorithm.HMAC256("secret"))
.withIssuer("auth0")
.build()
.verify(token);
}

@Test
public void shouldValidateSubject() throws Exception {
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.Rq8IxqeX7eA6GgYxlcHdPFVRNFFZc5rEI3MQTZZbK3I";
Expand Down Expand Up @@ -126,6 +150,18 @@ public void shouldThrowOnInvalidAudience() throws Exception {
.verify(token);
}

@Test
public void shouldRemoveAudienceWhenPassingNull() throws Exception {
Algorithm algorithm = mock(Algorithm.class);
JWTVerifier verifier = JWTVerifier.init(algorithm)
.withAudience("John")
.withAudience(null)
.build();

assertThat(verifier.claims, is(notNullValue()));
assertThat(verifier.claims, not(hasKey("aud")));
}

@Test
public void shouldThrowOnNullCustomClaimName() throws Exception {
exception.expect(IllegalArgumentException.class);
Expand Down