Remove dependency on commons-codec by using java.util.Base64
Closes gh-11318
This commit is contained in:
+62
-4
@@ -18,15 +18,14 @@ package org.springframework.security.saml2.provider.service.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.function.Function;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.InflaterOutputStream;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.codec.CodecPolicy;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.saml2.core.Saml2Error;
|
||||
@@ -49,7 +48,11 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public final class Saml2AuthenticationTokenConverter implements AuthenticationConverter {
|
||||
|
||||
private static Base64 BASE64 = new Base64(0, new byte[] { '\n' }, false, CodecPolicy.STRICT);
|
||||
// MimeDecoder allows extra line-breaks as well as other non-alphabet values.
|
||||
// This matches the behaviour of the commons-codec decoder.
|
||||
private static final Base64.Decoder BASE64 = Base64.getMimeDecoder();
|
||||
|
||||
private static final Base64Checker BASE_64_CHECKER = new Base64Checker();
|
||||
|
||||
private final RelyingPartyRegistrationResolver relyingPartyRegistrationResolver;
|
||||
|
||||
@@ -127,6 +130,7 @@ public final class Saml2AuthenticationTokenConverter implements AuthenticationCo
|
||||
|
||||
private byte[] samlDecode(String base64EncodedPayload) {
|
||||
try {
|
||||
BASE_64_CHECKER.checkAcceptable(base64EncodedPayload);
|
||||
return BASE64.decode(base64EncodedPayload);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
@@ -149,4 +153,58 @@ public final class Saml2AuthenticationTokenConverter implements AuthenticationCo
|
||||
}
|
||||
}
|
||||
|
||||
static class Base64Checker {
|
||||
|
||||
private static final int[] values = genValueMapping();
|
||||
|
||||
Base64Checker() {
|
||||
|
||||
}
|
||||
|
||||
private static int[] genValueMapping() {
|
||||
byte[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
.getBytes(StandardCharsets.ISO_8859_1);
|
||||
|
||||
int[] values = new int[256];
|
||||
Arrays.fill(values, -1);
|
||||
for (int i = 0; i < alphabet.length; i++) {
|
||||
values[alphabet[i] & 0xff] = i;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
boolean isAcceptable(String s) {
|
||||
int goodChars = 0;
|
||||
int lastGoodCharVal = -1;
|
||||
|
||||
// count number of characters from Base64 alphabet
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
int val = values[0xff & s.charAt(i)];
|
||||
if (val != -1) {
|
||||
lastGoodCharVal = val;
|
||||
goodChars++;
|
||||
}
|
||||
}
|
||||
|
||||
// in cases of an incomplete final chunk, ensure the unused bits are zero
|
||||
switch (goodChars % 4) {
|
||||
case 0:
|
||||
return true;
|
||||
case 2:
|
||||
return (lastGoodCharVal & 0b1111) == 0;
|
||||
case 3:
|
||||
return (lastGoodCharVal & 0b11) == 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void checkAcceptable(String ins) {
|
||||
if (!isAcceptable(ins)) {
|
||||
throw new IllegalArgumentException("Unaccepted Encoding");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user