Извлечение параметров в сервисе traefik.frontend.auth.forward.address - PullRequest
0 голосов
/ 12 января 2019

Резюме

Я пытаюсь настроить аутентификацию, используя настройку Traefik traefik.frontend.auth.forward.address. Мой основной веб-сервис имеет метку traefik.frontend.auth.forward.address=login.mydomain.com на контейнере. Кажется, что Traefik правильно перенаправляет входящие запросы, предназначенные для mydomain.com на login.mydomain.com, но при отправке формы входа в систему запрос POST превращается в запрос GET, прежде чем он попадает в службу входа в систему, и параметры исходного запроса POST кажутся быть пропущенным. Пользователь не может войти в систему.

Контейнеры

docker run -d \
    -l "traefik.frontend.rule=Host:login.mydomain.com; Method:GET, POST" \
    -l "traefik.enable=true" \
    login-service

docker run -d \
    -l "traefik.frontend.rule=Host:mydomain.com" \
    -l "traefik.frontend.auth.forward.address=https://login.mydomain.com" \
    -l "traefik.frontend.auth.forward.authResponseHeaders=cookie" \
    -l "traefik.enable=true" \
    web-service

Вопрос

Используя auth.forward.address, я должен увидеть параметры из исходного запроса POST в моей службе входа в систему? Так как Traefik превращает его в запрос GET, где в этом запросе я должен искать параметры? Или, может быть, я что-то неправильно настроил? Может быть, отсутствует флаг authResponseHeaders? 1016 *

Что работает

Запросы на mydomain.com показывать форму входа с login-service, с продолжением показа URL mydomain.com; перенаправление на login.mydomain.com происходит за кулисами, и это правильно.

Я также сам проверил службу входа в систему, и, похоже, она работает. Он размещает форму, которая отправляет POST-запрос службе, а затем отвечает 200 OK и заголовком Set-Cookie. Фактически, когда я перехожу к login.mydomain.com напрямую, я могу войти в систему, которая устанавливает мой cookie, и я могу перейти к mydomain.com и пропустить экран входа в систему.

Что не работает

При отправке формы входа в систему запрос POST достигает login-service (что подтверждается журналами в этой службе) как запрос GET, и данные в запросе POST исчезают. Traefik добавляет x-forwarded-method, установленный на POST, но я не могу найти данные в исходном запросе POST. Мне нужны параметры из формы входа в систему для их проверки, и они, похоже, не доходят до службы входа.

Конфигурация Traefik

Я не думаю, что что-то о моей конфигурации Traefik уместно здесь, но я включил это для полноты.

checkNewVersion = true
logLevel = "DEBUG"
defaultEntryPoints = ["https","http"]
sendAnonymousUsage = true

[api]
dashboard = true
debug = true

[entryPoints]
[entryPoints.http]
address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]

[retry]

[docker]
endpoint = "unix:///var/run/docker.sock"
watch = true
exposedbydefault = false

[acme]
email = "admin@mydomain.com"
storage = "acme.json"
entryPoint = "https"
OnHostRule = true

[acme.httpChallenge]
entryPoint = "http"

1 Ответ

0 голосов
/ 16 января 2019

Я выследил Код форварда Traefik . Конечно же, тело запроса не передается в нисходящий поток в службу аутентификации; только заголовки делают это так далеко. Так много для поведения отправки формы по умолчанию.

Чтобы обойти это, я переработал свою логику аутентификации на стороне клиента, чтобы отправить POST-запрос с учетными данными в заголовке вместо тела, задав XMLHttpRequest.setRequestHeader.

Есть еще один улов, необходимый для его работы. Мне нужно установить куки на стороне клиента, используя заголовок Set-Cookie, возвращаемый с сервера аутентификации, но если сервер вернет 200 OK, когда вход в систему будет успешным, Traefik немедленно передаст исходный запрос в пункт назначения пользователя - это означает, что заголовок Set-Cookie никогда не будет доступен пользователю. Чтобы обойти это, я вернул 418 I'm a teapot, когда аутентификация прошла успешно. Это позволяет заголовку Set-Cookie возвращать его в браузер пользователя, чтобы можно было установить маркер авторизации пользователя. Затем клиент автоматически перезагружает нужную страницу, на этот раз с правильным набором файлов cookie, и теперь сервер аутентификации возвращает 200 OK, если он видит действительный файл cookie для запрошенной службы.

Вот как выглядит код на стороне клиента:

<form id="form" method="post" action="/">
    Username: <input type="text" name="username" />
    Password: <input type="password" name="password" />
    <input type="submit" value="Submit" />
</form>
<script>
    // Override the default form submit behavior.
    // Traefik doesn't pass along body as part of proxying to the auth server,
    // so the credentials have to be put in the headers instead.
    const form = document.getElementById("form");
    form.addEventListener('submit', function(event) {
        const data = new FormData(form);
        var request = new XMLHttpRequest();
        request.open("POST", "/", true);
        request.setRequestHeader("Auth-Form", new URLSearchParams(data).toString());
        request.withCredentials = true;
        request.onload = function(e) {
            if (request.status == 418) {
                window.location = window.location.href;
            } else {
                alert("Login failed.");
            }
        };
        request.send(data);
        event.preventDefault();
    }, false);
</script>

Я оставляю этот вопрос открытым, по крайней мере, пока не кончится щедрость, потому что я не могу себе представить, что это намеченный способ сделать это. Я надеюсь, что кто-то может оценить, как traefik.frontend.auth.forward.address предполагается использовать. Или, если кто-то использовал другую стратегию прокси-сервера аутентификации с Traefik, мне не терпится услышать об этом.

...