diff --git a/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/DefaultJWTParser.java b/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/DefaultJWTParser.java index 74dc37e2..4c712be5 100644 --- a/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/DefaultJWTParser.java +++ b/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/DefaultJWTParser.java @@ -29,7 +29,11 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; +import org.eclipse.microprofile.jwt.Claims; import org.eclipse.microprofile.jwt.JsonWebToken; +import org.jose4j.jwt.JwtClaims; +import org.jose4j.jwt.consumer.InvalidJwtException; +import org.jose4j.jwt.consumer.JwtConsumerBuilder; import io.smallrye.jwt.algorithm.KeyEncryptionAlgorithm; import io.smallrye.jwt.algorithm.SignatureAlgorithm; @@ -175,4 +179,19 @@ private static boolean isEdECPublicKey(Key verificationKey) { private static boolean isXecPrivateKey(Key encKey) { return KeyUtils.isSupportedKey(encKey, XEC_PRIVATE_KEY_INTERFACE); } + + @Override + public JsonWebToken parseOnly(String token) throws ParseException { + try { + JwtClaims claims = new JwtConsumerBuilder() + .setSkipSignatureVerification() + .setSkipAllValidators() + .build().processToClaims(token); + claims.setClaim(Claims.raw_token.name(), token); + return new DefaultJWTCallerPrincipal(claims); + } catch (InvalidJwtException e) { + PrincipalMessages.msg.failedToVerifyToken(e); + } + return null; + } } diff --git a/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/JWTParser.java b/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/JWTParser.java index 635f0000..40657c6e 100644 --- a/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/JWTParser.java +++ b/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/JWTParser.java @@ -120,4 +120,9 @@ public interface JWTParser { */ public JsonWebToken decrypt(final String token, String secret) throws ParseException; + /** + * Parse an already verified signed JWT token. + * Use this method only if the token has been verified by the secure gateway or other systems. + */ + public JsonWebToken parseOnly(final String token) throws ParseException; } diff --git a/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/PrincipalMessages.java b/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/PrincipalMessages.java index a75c74b5..7b696fa5 100644 --- a/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/PrincipalMessages.java +++ b/implementation/jwt-auth/src/main/java/io/smallrye/jwt/auth/principal/PrincipalMessages.java @@ -84,4 +84,6 @@ interface PrincipalMessages { @Message(id = 7021, value = "JWK set does not contain provided token 'kid'") UnmatchedTokenKidException unmatchedTokenKidException(); + @Message(id = 7022, value = "Failed to parse a token") + ParseException failedToParseToken(@Cause Throwable throwable); } \ No newline at end of file diff --git a/testsuite/basic/src/test/java/io/smallrye/jwt/auth/principal/DefaultJWTParserTest.java b/testsuite/basic/src/test/java/io/smallrye/jwt/auth/principal/DefaultJWTParserTest.java index 6a6ffe54..f87fa938 100644 --- a/testsuite/basic/src/test/java/io/smallrye/jwt/auth/principal/DefaultJWTParserTest.java +++ b/testsuite/basic/src/test/java/io/smallrye/jwt/auth/principal/DefaultJWTParserTest.java @@ -28,6 +28,13 @@ import io.smallrye.jwt.util.ResourceUtils; class DefaultJWTParserTest { + @Test + void parseOnly() throws Exception { + String jwtString = Jwt.upn("jdoe@example.com").sign(KeyUtils.readPrivateKey("/privateKey.pem")); + JsonWebToken jwt = new DefaultJWTParser().parseOnly(jwtString); + assertEquals("jdoe@example.com", jwt.getName()); + } + @Test void parseWithConfiguredPublicKey() throws Exception { String jwtString = Jwt.upn("jdoe@example.com").issuer("https://server.example.com")