Skip to content

Commit

Permalink
Merge d452c2c into ac73b1c
Browse files Browse the repository at this point in the history
  • Loading branch information
ricveal committed Jul 15, 2017
2 parents ac73b1c + d452c2c commit a8a303a
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 28 deletions.
40 changes: 40 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,46 @@
<version>4.3.0</version>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.codehaus.gmaven
</groupId>
<artifactId>
gmaven-plugin
</artifactId>
<versionRange>
[1.5,)
</versionRange>
<goals>
<goal>generateStubs</goal>
<goal>testCompile</goal>
<goal>
generateTestStubs
</goal>
<goal>compile</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/jsonwebtoken/Claims.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ public interface Claims extends Map<String, Object>, ClaimsMutator<Claims> {
*
* @return the JWT {@code aud} value or {@code null} if not present.
*/
String getAudience();
String[] getAudience();

/**
* {@inheritDoc}
*/
@Override //only for better/targeted JavaDoc
Claims setAudience(String aud);
Claims setAudience(String ... aud);

/**
* Returns the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.4">
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/jsonwebtoken/ClaimsMutator.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public interface ClaimsMutator<T extends ClaimsMutator> {
*
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
*/
T setAudience(String aud);
*/
T setAudience(String ... aud);

/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.4">
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/io/jsonwebtoken/JwtBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,19 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* <p>The method allows to insert multiple audiences if desired</p>
*
* <pre>
* String jwt = Jwts.builder().setAudience("You", "Administrators").compact();
* </pre>
*
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
* @since 0.2
*/
@Override //only for better/targeted JavaDoc
JwtBuilder setAudience(String aud);
JwtBuilder setAudience(String ... aud);

/**
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.4">
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/jsonwebtoken/JwtParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public interface JwtParser {
* @see MissingClaimException
* @see IncorrectClaimException
*/
JwtParser requireAudience(String audience);
JwtParser requireAudience(String ... audience);

/**
* Ensures that the specified {@code iss} exists in the parsed JWT. If missing or if the parsed
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/io/jsonwebtoken/impl/DefaultClaims.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.jsonwebtoken.RequiredTypeException;

import java.util.Date;
import java.util.List;
import java.util.Map;

public class DefaultClaims extends JwtMap implements Claims {
Expand Down Expand Up @@ -54,12 +55,18 @@ public Claims setSubject(String sub) {
}

@Override
public String getAudience() {
return getString(AUDIENCE);
public String[] getAudience() {
Object v = get(AUDIENCE);
if (v == null) {
return null;
}
List<String> aud = (List<String>) v;
String[] audience = aud.toArray(new String[0]);
return audience;
}

@Override
public Claims setAudience(String aud) {
public Claims setAudience(String ... aud) {
setValue(AUDIENCE, aud);
return this;
}
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,19 @@ public JwtBuilder setSubject(String sub) {
}
return this;
}

@Override
public JwtBuilder setAudience(String aud) {
if (Strings.hasText(aud)) {
ensureClaims().setAudience(aud);
@Override
public JwtBuilder setAudience(String ... aud) {
if (aud != null) {
ensureClaims().setAudience(aud);
} else {
if (this.claims != null) {
claims.setAudience(aud);
//noinspection ConstantConditions
this.claims.setAudience(aud);
}
}
return this;
}
}

@Override
public JwtBuilder setExpiration(Date exp) {
Expand Down
21 changes: 18 additions & 3 deletions src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
import java.io.IOException;
import java.security.Key;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -88,7 +90,7 @@ public JwtParser requireIssuer(String issuer) {
}

@Override
public JwtParser requireAudience(String audience) {
public JwtParser requireAudience(String ... audience) {
expectedClaims.setAudience(audience);
return this;
}
Expand Down Expand Up @@ -433,7 +435,10 @@ private void validateExpectedClaims(Header header, Claims claims) {
) {
expectedClaimValue = expectedClaims.get(expectedClaimName, Date.class);
actualClaimValue = claims.get(expectedClaimName, Date.class);
} else if (
} else if (Claims.AUDIENCE.equals(expectedClaimName)) {
expectedClaimValue = Arrays.asList((String[]) expectedClaimValue);
}
else if (
expectedClaimValue instanceof Date &&
actualClaimValue != null &&
actualClaimValue instanceof Long
Expand All @@ -449,7 +454,17 @@ private void validateExpectedClaims(Header header, Claims claims) {
expectedClaimName, expectedClaimValue
);
invalidClaimException = new MissingClaimException(header, claims, msg);
} else if (!expectedClaimValue.equals(actualClaimValue)) {
} else if (Claims.AUDIENCE.equals(expectedClaimName) ) {
List<String> actualClaimValueList = (List) actualClaimValue;
if (!actualClaimValueList.containsAll((List) expectedClaimValue)){
String msg = String.format(
ClaimJwtException.INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE,
expectedClaimName, expectedClaimValue, actualClaimValueList
);
invalidClaimException = new IncorrectClaimException(header, claims, msg);
}
}
else if (!expectedClaimValue.equals(actualClaimValue)) {
String msg = String.format(
ClaimJwtException.INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE,
expectedClaimName, expectedClaimValue, actualClaimValue
Expand Down
133 changes: 130 additions & 3 deletions src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -1092,11 +1092,47 @@ class JwtParserTest {
}

@Test
void testParseRequireAudience_Success() {
void testParseRequireSingleAudience_Success() {
def audience = 'A Most Awesome Audience'

byte[] key = randomKey()

String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setAudience(audience).
compact()

Jwt<Header,Claims> jwt = Jwts.parser().setSigningKey(key).
requireAudience(audience).
parseClaimsJws(compact)

assertEquals jwt.getBody().getAudience()[0], audience
}

@Test
void testParseRequireSingleAudience2_Success() {
String requiredAudience = 'A Most Awesome Audience'

String[] audience = [requiredAudience, 'Another Awesome Audience']

byte[] key = randomKey()

String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setAudience(audience).
compact()

Jwt<Header,Claims> jwt = Jwts.parser().setSigningKey(key).
requireAudience(requiredAudience).
parseClaimsJws(compact)

assertEquals jwt.getBody().getAudience(), audience
}

@Test
void testParseRequireMultipleAudience_Success() {
String[] audience = ['A Most Awesome Audience', 'Other Awesome Audience']

byte[] key = randomKey()

String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setAudience(audience).
compact()
Expand All @@ -1108,6 +1144,26 @@ class JwtParserTest {
assertEquals jwt.getBody().getAudience(), audience
}

@Test
void testParseRequireMultipleAudience2_Success() {

String requiredAudience = ['A Most Awesome Audience', 'Other Awesome Audience']

String[] audience = [requiredAudience, 'Another Awesome Audience']

byte[] key = randomKey()

String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setAudience(audience).
compact()

Jwt<Header,Claims> jwt = Jwts.parser().setSigningKey(key).
requireAudience(audience).
parseClaimsJws(compact)

assertEquals jwt.getBody().getAudience(), audience
}

@Test
void testParseRequireAudience_Incorrect_Fail() {
def goodAudience = 'A Most Awesome Audience'
Expand All @@ -1126,12 +1182,60 @@ class JwtParserTest {
fail()
} catch(IncorrectClaimException e) {
assertEquals(
String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, goodAudience, badAudience),
String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, [goodAudience], [badAudience]),
e.getMessage()
)
}
}

@Test
void testParseRequireMultipleAudience_Incorrect_Fail() {
String[] goodAudience = ['A Most Awesome Audience', 'Another Most Awesome Audience']
String[] badAudience = ['A Most Bogus Audience', 'Another Most Bogus Audience']

byte[] key = randomKey()

String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setAudience(badAudience).
compact()

try {
Jwts.parser().setSigningKey(key).
requireAudience(goodAudience).
parseClaimsJws(compact)
fail()
} catch(IncorrectClaimException e) {
assertEquals(
String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, "[A Most Awesome Audience, Another Most Awesome Audience]", "[A Most Bogus Audience, Another Most Bogus Audience]"),
e.getMessage()
)
}
}

@Test
void testParseRequireIncompleteMultipleAudience_Incorrect_Fail() {
String[] goodAudience = ['A Most Awesome Audience', 'Another Most Awesome Audience']
def badAudience = 'A Most Awesome Audience'

byte[] key = randomKey()

String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setAudience(badAudience).
compact()

try {
Jwts.parser().setSigningKey(key).
requireAudience(goodAudience).
parseClaimsJws(compact)
fail()
} catch(IncorrectClaimException e) {
assertEquals(
String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, "[A Most Awesome Audience, Another Most Awesome Audience]", [badAudience]),
e.getMessage()
)
}
}

@Test
void testParseRequireAudience_Missing_Fail() {
def audience = 'A Most Awesome audience'
Expand All @@ -1149,12 +1253,35 @@ class JwtParserTest {
fail()
} catch(MissingClaimException e) {
assertEquals(
String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, audience),
String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, [audience]),
e.getMessage()
)
}
}

@Test
void testParseRequireMultipleAudience_Missing_Fail() {
String[] audience = ['A Most Awesome Audience', 'Another Most Awesome Audience']

byte[] key = randomKey()

String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setId('id').
compact()

try {
Jwts.parser().setSigningKey(key).
requireAudience(audience).
parseClaimsJws(compact)
fail()
} catch(MissingClaimException e) {
assertEquals(
String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, "[A Most Awesome Audience, Another Most Awesome Audience]"),
e.getMessage()
)
}
}

@Test
void testParseRequireSubject_Success() {
def subject = 'A Most Awesome Subject'
Expand Down

0 comments on commit a8a303a

Please sign in to comment.