diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java index 85df9e28b040..157812db14fc 100644 --- a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java @@ -158,9 +158,9 @@ protected Map decodeJWT(String jwt) throws IOException if (sections.length != 3) throw new IllegalArgumentException("JWT does not contain 3 sections"); - Base64.Decoder decoder = Base64.getDecoder(); - String jwtHeaderString = new String(decoder.decode(sections[0]), StandardCharsets.UTF_8); - String jwtClaimString = new String(decoder.decode(sections[1]), StandardCharsets.UTF_8); + Base64.Decoder decoder = Base64.getUrlDecoder(); + String jwtHeaderString = new String(decoder.decode(padJWTSection(sections[0])), StandardCharsets.UTF_8); + String jwtClaimString = new String(decoder.decode(padJWTSection(sections[1])), StandardCharsets.UTF_8); String jwtSignature = sections[2]; Map jwtHeader = (Map)JSON.parse(jwtHeaderString); @@ -175,6 +175,29 @@ and the Token Endpoint (which it is in this flow), the TLS server validation return (Map)JSON.parse(jwtClaimString); } + private static byte[] padJWTSection(String unpaddedEncodedJwtSection) + { + int length = unpaddedEncodedJwtSection.length(); + int remainder = length % 4; + byte[] bytes; + + if (remainder > 0) + { + int paddingNeeded = 4 - remainder; + byte[] padding = { '=', '=', '=' }; + bytes = new byte[length + paddingNeeded]; + + System.arraycopy(unpaddedEncodedJwtSection.getBytes(), 0, bytes, 0, length); + System.arraycopy(padding, 0, bytes, length, paddingNeeded); + } + else + { + bytes = unpaddedEncodedJwtSection.getBytes(); + } + + return bytes; + } + private Map claimAuthCode(String authCode) throws IOException { if (LOG.isDebugEnabled())