From 4cab1381deb377e9128392501e97e05f1e9a6442 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Mon, 16 Oct 2023 17:28:23 +0100 Subject: [PATCH] Support for the scope claim in JWT Build API (#729) --- .../main/java/io/smallrye/jwt/build/Jwt.java | 20 +++++++++++++++ .../smallrye/jwt/build/JwtClaimsBuilder.java | 25 +++++++++++++++++-- .../jwt/build/impl/JwtClaimsBuilderImpl.java | 14 +++++------ .../io/smallrye/jwt/build/JwtSignTest.java | 6 ++++- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/Jwt.java b/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/Jwt.java index 9c449015..7a110d42 100644 --- a/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/Jwt.java +++ b/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/Jwt.java @@ -187,6 +187,26 @@ public static JwtClaimsBuilder groups(Set groups) { return claims().groups(groups); } + /** + * Creates a new instance of {@link JwtClaimsBuilder} with a specified 'scope' claim. + * + * @param scope the scope + * @return {@link JwtClaimsBuilder} + */ + public static JwtClaimsBuilder scope(String scope) { + return claims().scope(scope); + } + + /** + * Creates a new instance of {@link JwtClaimsBuilder} with a specified 'scope' claim. + * + * @param scopes the scopes + * @return {@link JwtClaimsBuilder} + */ + public static JwtClaimsBuilder scope(Set scopes) { + return claims().scope(scopes); + } + /** * Creates a new instance of {@link JwtClaimsBuilder} with a specified 'audience' claim. * diff --git a/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/JwtClaimsBuilder.java b/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/JwtClaimsBuilder.java index a0cb40c3..18326071 100644 --- a/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/JwtClaimsBuilder.java +++ b/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/JwtClaimsBuilder.java @@ -132,7 +132,9 @@ default JwtClaimsBuilder expiresIn(Duration expiresIn) { * @param group the groups * @return JwtClaimsBuilder */ - JwtClaimsBuilder groups(String group); + default JwtClaimsBuilder groups(String group) { + return groups(Set.of(group)); + } /** * Set a multiple value 'groups' claim @@ -142,6 +144,25 @@ default JwtClaimsBuilder expiresIn(Duration expiresIn) { */ JwtClaimsBuilder groups(Set groups); + /** + * Set a 'scope' claim value + * + * @param scope the scope + * @return JwtClaimsBuilder + */ + default JwtClaimsBuilder scope(String scope) { + return scope(Set.of(scope)); + } + + /** + * Set a multiple value 'scope' claim whose value will be represented as a String + * where each scope value is separated by the " " space character. + * + * @param scopes the scopes + * @return JwtClaimsBuilder + */ + JwtClaimsBuilder scope(Set scopes); + /** * Set a single value audience 'aud' claim * @@ -151,7 +172,7 @@ default JwtClaimsBuilder expiresIn(Duration expiresIn) { JwtClaimsBuilder audience(String audience); /** - * Set a multiple value audience 'aud' claim + * Set a multiple value audience 'aud' claim whose value will be represented as a JSON array * * @param audiences the audiences * @return JwtClaimsBuilder diff --git a/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/impl/JwtClaimsBuilderImpl.java b/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/impl/JwtClaimsBuilderImpl.java index 92173fee..124d102a 100644 --- a/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/impl/JwtClaimsBuilderImpl.java +++ b/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/impl/JwtClaimsBuilderImpl.java @@ -35,6 +35,7 @@ */ class JwtClaimsBuilderImpl extends JwtSignatureImpl implements JwtClaimsBuilder, JwtSignatureBuilder { + private static final String SCOPE_CLAIM = "scope"; private static final StringVerifier STRING_VERIFIER = new StringVerifier(); private static final InstantVerifier INSTANT_VERIFIER = new InstantVerifier(); private static final StringCollectionVerifier STRING_COLLECTION_VERIFIER = new StringCollectionVerifier(); @@ -167,16 +168,14 @@ public JwtClaimsBuilder expiresIn(long expiresIn) { * {@inheritDoc} */ @Override - public JwtClaimsBuilder groups(String group) { - return groups(Collections.singleton(group)); + public JwtClaimsBuilder groups(Set groups) { + claims.setClaim(Claims.groups.name(), groups.stream().collect(Collectors.toList())); + return this; } - /** - * {@inheritDoc} - */ @Override - public JwtClaimsBuilder groups(Set groups) { - claims.setClaim(Claims.groups.name(), groups.stream().collect(Collectors.toList())); + public JwtClaimsBuilder scope(Set scopes) { + claims.setClaim(SCOPE_CLAIM, scopes.stream().collect(Collectors.joining(" "))); return this; } @@ -383,5 +382,4 @@ public JwtClaimsBuilder remove(String name) { claims.unsetClaim(name); return this; } - } diff --git a/implementation/jwt-build/src/test/java/io/smallrye/jwt/build/JwtSignTest.java b/implementation/jwt-build/src/test/java/io/smallrye/jwt/build/JwtSignTest.java index e4a98563..9904e6a0 100644 --- a/implementation/jwt-build/src/test/java/io/smallrye/jwt/build/JwtSignTest.java +++ b/implementation/jwt-build/src/test/java/io/smallrye/jwt/build/JwtSignTest.java @@ -489,6 +489,7 @@ static void checkDefaultClaimsAndHeaders(Map headers, JwtClaims @Test void signClaimsAllTypes() throws Exception { String jwt = Jwt.claims() + .scope(Set.of("read:data", "write:data")) .claim("stringClaim", "string") .claim("booleanClaim", true) .claim("numberClaim", 3) @@ -502,9 +503,12 @@ void signClaimsAllTypes() throws Exception { JsonWebSignature jws = getVerifiedJws(jwt); JwtClaims claims = JwtClaims.parse(jws.getPayload()); - assertEquals(11, claims.getClaimsMap().size()); + assertEquals(12, claims.getClaimsMap().size()); checkDefaultClaimsAndHeaders(getJwsHeaders(jwt, 2), claims); + String scope = claims.getStringClaimValue("scope"); + assertTrue("read:data write:data".equals(scope) || "write:data read:data".equals(scope)); + assertEquals("string", claims.getClaimValue("stringClaim")); assertTrue((Boolean) claims.getClaimValue("booleanClaim")); assertEquals(3L, claims.getClaimValue("numberClaim"));