Тип интеграции — интеграция прокси-сервера Lambda с payloadFormatVersion: 2.0.
Все работает нормально, за исключением того, что параметры запроса изменяются API Gateway до достижения моего приложения Spring Boot.
проблема
Когда я вызываю эту конечную точку:
Код: Выделить всё
GET https://api.example.com/welcome?param1=aGVsbG8gbXkgbmFtZSBpcyBqb2huCg==
Код: Выделить всё
DEBUG --- Securing GET /welcome?param1=aGVsbG8gbXkgbmFtZSBpcyBqb2huCg==
DEBUG --- GET "/welcome?param1=aGVsbG8gbXkgbmFtZSBpcyBqb2huCg=="
INFO --- preHandle: method=GET, uri=/welcome, parameters=[param1=aGVsbG8gbXkgbmFtZSBpcyBqb2huCg]
Код: Выделить всё
==но к тому моменту, когда Spring обработает это, заполнение отсутствует.
Что я пробовал
Чтобы обойти эту проблему, я добавил фильтр, который пытается автоматически восстанавливать отсутствующее заполнение Base64 при необходимости:
Код: Выделить всё
@Component
@Order(HIGHEST_PRECEDENCE)
public class Base64PaddingFixFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
var originalParams = request.getParameterMap();
var fixedParams = originalParams.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> Arrays.stream(e.getValue())
.map(Base64PaddingFixFilter::padBase64IfNeeded)
.toArray(String[]::new)));
var hasModifiedParams = !fixedParams.equals(originalParams);
if (hasModifiedParams) {
var wrapped = new FixedParamsRequestWrapper(request, fixedParams);
filterChain.doFilter(wrapped, response);
} else {
filterChain.doFilter(request, response);
}
}
private static String padBase64IfNeeded(String s) {
if (s == null) return null;
var len = s.length();
if (len == 0) return s;
var base64UrlPattern = "^[A-Za-z0-9_\\-]+=*$";
if (!s.matches(base64UrlPattern)) return s;
var mod = len % 4;
if (mod == 0) return s;
var pad = 4 - mod;
return s + "=".repeat(pad);
}
private static class FixedParamsRequestWrapper extends HttpServletRequestWrapper {
private final Map fixedParams;
public FixedParamsRequestWrapper(HttpServletRequest request, Map fixedParams) {
super(request);
this.fixedParams = fixedParams;
}
@Override public String getParameter(String name) {
var values = fixedParams.get(name);
return (values != null && values.length > 0) ? values[0] : null;
}
@Override public Map getParameterMap() { return fixedParams; }
@Override public String[] getParameterValues(String name) { return fixedParams.get(name); }
}
}
Проблема с этим обходным решением
Если параметр запроса не Base64, но соответствует шаблону Base64 (
Код: Выделить всё
[A-Za-z0-9_-]+=*фильтр неправильно добавляет к нему дополнение, рассматривая его как «поврежденное» значение Base64.
Пример:
Код: Выделить всё
GET /welcome?param1=abc
Код: Выделить всё
param1=abc=
Таким образом, этот подход ненадежен, если все параметры запроса не гарантированно закодированы в Base64.
Вопросы
[*]Почему API Gateway HTTP API v2 удаляет или изменяет заполнение (
Код: Выделить всё
=[*]Есть ли способ настроить API-шлюз так, чтобы сохранять параметры запроса в том виде, в котором они были отправлены (без декодирования/перекодирования)?
[*]Есть ли более надежный обходной путь, чем проверка и повторное заполнение параметров вручную?
Подробнее здесь: https://stackoverflow.com/questions/798 ... s-when-cal
Мобильная версия