diff --git a/implementation/src/main/java/io/smallrye/jwt/auth/cdi/RawClaimTypeProducer.java b/implementation/src/main/java/io/smallrye/jwt/auth/cdi/RawClaimTypeProducer.java index 07cb6d60..aa10aecb 100644 --- a/implementation/src/main/java/io/smallrye/jwt/auth/cdi/RawClaimTypeProducer.java +++ b/implementation/src/main/java/io/smallrye/jwt/auth/cdi/RawClaimTypeProducer.java @@ -26,6 +26,7 @@ import javax.inject.Inject; import javax.json.JsonNumber; import javax.json.JsonString; +import javax.json.JsonValue; import org.eclipse.microprofile.jwt.Claim; import org.eclipse.microprofile.jwt.Claims; @@ -120,6 +121,33 @@ Double getClaimAsDouble(InjectionPoint ip) { return returnValue; } + @Produces + @Claim("") + Boolean getClaimAsBoolean(InjectionPoint ip) { + log.debugf("getClaimAsBoolean(%s)", ip); + if (currentToken == null) { + return null; + } + + String name = getName(ip); + Optional optValue = currentToken.claim(name); + Boolean returnValue = null; + if (optValue.isPresent()) { + Object value = optValue.get(); + if (value instanceof JsonValue) { + final JsonValue.ValueType valueType = ((JsonValue) value).getValueType(); + if (valueType.equals(JsonValue.ValueType.TRUE)) { + returnValue = true; + } else if (valueType.equals(JsonValue.ValueType.FALSE)) { + returnValue = false; + } + } else { + returnValue = Boolean.valueOf(value.toString()); + } + } + return returnValue; + } + /** * Produces a *raw* Optional value. * diff --git a/implementation/src/main/java/io/smallrye/jwt/auth/principal/DefaultJWTCallerPrincipal.java b/implementation/src/main/java/io/smallrye/jwt/auth/principal/DefaultJWTCallerPrincipal.java index ae52a551..bb650cdc 100644 --- a/implementation/src/main/java/io/smallrye/jwt/auth/principal/DefaultJWTCallerPrincipal.java +++ b/implementation/src/main/java/io/smallrye/jwt/auth/principal/DefaultJWTCallerPrincipal.java @@ -25,6 +25,7 @@ import javax.json.JsonArray; import javax.json.JsonNumber; import javax.json.JsonObject; +import javax.json.JsonValue; import org.eclipse.microprofile.jwt.Claims; import org.jboss.logging.Logger; @@ -161,6 +162,8 @@ private void fixJoseTypes() { replaceMap(name); } else if (claimValue instanceof Number) { replaceNumber(name); + } else if (claimValue instanceof Boolean) { + replaceBoolean(name); } } } @@ -218,4 +221,14 @@ protected void replaceNumber(String name) { LOGGER.warn("replaceNumber failure for: " + name, e); } } -} \ No newline at end of file + + protected void replaceBoolean(String name) { + try { + Boolean bool = claimsSet.getClaimValue(name, Boolean.class); + JsonValue jsonBoolean = JsonUtils.wrapValue(bool); + claimsSet.setClaim(name, jsonBoolean); + } catch (MalformedClaimException e) { + LOGGER.warn("replaceNumber failure for: " + name, e); + } + } +} diff --git a/implementation/src/test/java/io/smallrye/jwt/auth/cdi/ClaimInjectionTest.java b/implementation/src/test/java/io/smallrye/jwt/auth/cdi/ClaimInjectionTest.java new file mode 100644 index 00000000..0fe7af17 --- /dev/null +++ b/implementation/src/test/java/io/smallrye/jwt/auth/cdi/ClaimInjectionTest.java @@ -0,0 +1,117 @@ +package io.smallrye.jwt.auth.cdi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Produces; +import javax.inject.Inject; +import javax.json.JsonNumber; + +import org.eclipse.microprofile.jwt.Claim; +import org.eclipse.microprofile.jwt.ClaimValue; +import org.eclipse.microprofile.jwt.JsonWebToken; +import org.jboss.weld.junit4.WeldInitiator; +import org.jose4j.jws.JsonWebSignature; +import org.jose4j.jwt.JwtClaims; +import org.junit.Rule; +import org.junit.Test; + +import io.smallrye.jwt.KeyUtils; +import io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipal; +import io.smallrye.jwt.build.Jwt; + +@SuppressWarnings("CdiUnproxyableBeanTypesInspection") +public class ClaimInjectionTest { + @Rule + public WeldInitiator weld = WeldInitiator.from( + ClaimInjectionTest.class, + ClaimsBean.class, + RawClaimTypeProducer.class, + ClaimValueProducer.class, + CommonJwtProducer.class) + .addBeans() + .activate(RequestScoped.class) + .inject(this) + .build(); + + @Inject + private JsonWebToken jsonWebToken; + @Inject + private ClaimsBean claimsBean; + + @Test + public void inject() { + assertTrue(claimsBean.isBooleanClaim()); + assertTrue(claimsBean.getBooleanClaimWrapper()); + //assertTrue(claimsBean.getBooleanClaimValue().getValue()); // does not unwrap json to wrapper type + assertEquals(999, claimsBean.getLongClaim()); + assertEquals(999, claimsBean.getLongClaimWrapper().longValue()); + //assertEquals(999, claimsBean.getLongClaimValue().getValue().longValue()); // does not unwrap json to wrapper type + assertEquals(999, claimsBean.getLongClaimValueJson().getValue().longValue()); + } + + @Produces + @RequestScoped + private static JsonWebToken jwt() throws Exception { + String jwt = Jwt.claims("/token-claims.json").sign(); + JsonWebSignature jws = new JsonWebSignature(); + jws.setKey(KeyUtils.readPublicKey("/publicKey.pem")); + jws.setCompactSerialization(jwt); + JwtClaims claims = JwtClaims.parse(jws.getPayload()); + return new DefaultJWTCallerPrincipal(jwt, claims); + } + + @RequestScoped + private static class ClaimsBean { + @Inject + @Claim("boolean") + private boolean booleanClaim; + @Inject + @Claim("boolean") + private Boolean booleanClaimWrapper; + //@Inject + //(@Claim("boolean") + private ClaimValue booleanClaimValue; + @Inject + @Claim("long") + private long longClaim; + @Inject + @Claim("long") + private Long longClaimWrapper; + //@Inject + //@Claim("long") + private ClaimValue longClaimValue; + @Inject + @Claim("long") + private ClaimValue longClaimValueJson; + + boolean isBooleanClaim() { + return booleanClaim; + } + + Boolean getBooleanClaimWrapper() { + return booleanClaimWrapper; + } + + ClaimValue getBooleanClaimValue() { + return booleanClaimValue; + } + + long getLongClaim() { + return longClaim; + } + + Long getLongClaimWrapper() { + return longClaimWrapper; + } + + ClaimValue getLongClaimValue() { + return longClaimValue; + } + + ClaimValue getLongClaimValueJson() { + return longClaimValueJson; + } + } +} diff --git a/implementation/src/test/resources/token-claims.json b/implementation/src/test/resources/token-claims.json new file mode 100644 index 00000000..5d02fed7 --- /dev/null +++ b/implementation/src/test/resources/token-claims.json @@ -0,0 +1,20 @@ +{ + "iss": "https://server.example.com", + "jti": "a-123", + "sub": "24400320", + "upn": "jdoe@example.com", + "preferred_username": "jdoe", + "aud": "s6BhdRkqt3", + "exp": 1311281970, + "iat": 1311280970, + "auth_time": 1311280969, + + "byte": 1, + "short": 9, + "integer": 99, + "long": 999, + "float": 99.9, + "double": 99.99, + "boolean": true, + "char": "y" +}