diff --git a/.gitignore b/.gitignore index e06c352..ca3ddcd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,11 @@ -# Ignore Gradle project-specific cache directory -.gradle +# Gradle project-specific cache directory +/.gradle/ -# Ignore Gradle build output directory -build +# Gradle build output directory +/build/ -# Ignore Eclipse project files and directories -.classpath -.project -.settings +# IDE project files and directories +/.vscode/ +/.classpath +/.project +/.settings/ diff --git a/build.gradle b/build.gradle index 7f1be65..a94f858 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ sourceCompatibility = '1.8' targetCompatibility = '1.8' group = 'org.bsworks.catalina.authenticator.oidc' -version = '2.2.4' +version = '2.2.5' task jar(type: Jar, overwrite: true) {} jar.enabled = false diff --git a/src/common/java/org/bsworks/catalina/authenticator/oidc/BaseOpenIDConnectAuthenticator.java b/src/common/java/org/bsworks/catalina/authenticator/oidc/BaseOpenIDConnectAuthenticator.java index 6b39767..161d15c 100644 --- a/src/common/java/org/bsworks/catalina/authenticator/oidc/BaseOpenIDConnectAuthenticator.java +++ b/src/common/java/org/bsworks/catalina/authenticator/oidc/BaseOpenIDConnectAuthenticator.java @@ -21,6 +21,7 @@ import java.text.DateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Date; import java.util.List; import java.util.regex.Matcher; @@ -40,7 +41,6 @@ import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.buf.HexUtils; -import org.apache.tomcat.util.codec.binary.Base64; import org.apache.tomcat.util.descriptor.web.LoginConfig; import org.bsworks.util.json.JSONArray; import org.bsworks.util.json.JSONException; @@ -459,6 +459,17 @@ public String toString() { */ private static final Charset UTF8 = Charset.forName("UTF-8"); + /** + * URL-safe base64 decoder. + */ + private static final Base64.Decoder BASE64URL_DECODER = + Base64.getUrlDecoder(); + + /** + * Base64 encoder. + */ + private static final Base64.Encoder BASE64_ENCODER = Base64.getEncoder(); + /** * Name of the HTTP session note used to store the {@link Authorization} * object. @@ -1316,12 +1327,13 @@ protected Principal processAuthResponse(final Session session, // decode the ID token final String[] idTokenParts = authorization.getIdToken().split("\\."); final JSONObject idTokenHeader = new JSONObject(new JSONTokener( - new StringReader(new String(Base64.decodeBase64( + new StringReader(new String(BASE64URL_DECODER.decode( idTokenParts[0]), UTF8)))); final JSONObject idTokenPayload = new JSONObject(new JSONTokener( - new StringReader(new String(Base64.decodeBase64( + new StringReader(new String(BASE64URL_DECODER.decode( idTokenParts[1]), UTF8)))); - final byte[] idTokenSignature = Base64.decodeBase64(idTokenParts[2]); + final byte[] idTokenSignature = BASE64URL_DECODER.decode( + idTokenParts[2]); if (debug) this.log.debug("decoded ID token:" + "\n header: " + idTokenHeader @@ -1476,7 +1488,7 @@ protected boolean isSignatureValid(final OPDescriptor opDesc, } final Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(new SecretKeySpec(Base64.decodeBase64( + mac.init(new SecretKeySpec(BASE64URL_DECODER.decode( opDesc.getClientSecret()), "HmacSHA256")); mac.update(data.getBytes("ASCII")); final byte[] genSig = mac.doFinal(); @@ -1544,7 +1556,7 @@ protected TokenEndpointResponse callTokenEndpoint(final OPDescriptor opDesc, switch (opDesc.getTokenEndpointAuthMethod()) { case CLIENT_SECRET_BASIC: con.addRequestProperty("Authorization", - "Basic " + Base64.encodeBase64String( + "Basic " + BASE64_ENCODER.encodeToString( (opDesc.getClientId() + ":" + opDesc.getClientSecret()) .getBytes(UTF8))); break; @@ -1638,7 +1650,7 @@ protected boolean redirectToLandingPage(final Request request, * * @param request The request. * - * @return Base URL. + * @return Base URL. */ protected String getBaseURL(final Request request) { diff --git a/src/common/java/org/bsworks/catalina/authenticator/oidc/JWKSet.java b/src/common/java/org/bsworks/catalina/authenticator/oidc/JWKSet.java index 7391998..dfdadce 100644 --- a/src/common/java/org/bsworks/catalina/authenticator/oidc/JWKSet.java +++ b/src/common/java/org/bsworks/catalina/authenticator/oidc/JWKSet.java @@ -1,15 +1,16 @@ package org.bsworks.catalina.authenticator.oidc; +import java.math.BigInteger; import java.nio.charset.Charset; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPublicKeySpec; +import java.util.Base64; import java.util.HashMap; import java.util.Map; -import org.apache.tomcat.util.codec.binary.Base64; import org.bsworks.util.json.JSONArray; import org.bsworks.util.json.JSONObject; @@ -49,16 +50,19 @@ class JWKSet { this.keys = new HashMap<>(); try { final JSONArray keysProp = document.getJSONArray("keys"); + final Base64.Decoder base64 = Base64.getUrlDecoder(); for (int n = keysProp.length() - 1; n >= 0; n--) { final JSONObject keyDef = keysProp.getJSONObject(n); if (keyDef.optString("kty").equals("RSA") && keyDef.optString("use").equals("sig")) this.keys.put(keyDef.getString("kid"), keyFactory.generatePublic(new RSAPublicKeySpec( - Base64.decodeInteger(keyDef.getString("n") - .getBytes(ASCII)), - Base64.decodeInteger(keyDef.getString("e") - .getBytes(ASCII))))); + new BigInteger(1, base64.decode( + keyDef.getString("n").getBytes( + ASCII))), + new BigInteger(1, base64.decode( + keyDef.getString("e").getBytes( + ASCII)))))); } } catch (final InvalidKeySpecException e) { throw new IllegalArgumentException("Invalid key specification.", e);