Добавление базовой аутентификации на обратный прокси-сервер на основе Go

Я хочу защитить REST API демона Docker с помощью обратного прокси-сервера Go. Я нашел эту статью очень актуальной. Я никогда не использовал Go, поэтому не знаю, как реализовать базовую аутентификацию для этого со статическим именем пользователя и паролем. Я перепробовал все возможные способы, которые мне удалось найти в Google, но ни один из них не работал у меня.

Не могли бы некоторые помочь добавить статическую аутентификацию basicAuth в следующий код, чтобы запрос, чтобы API демона Docker был доступен только в том случае, если запрос включает имя пользователя и пароль: https://github.com/ben-lab/blog-material/blob/master/golang-reverse-proxy-2/reverse-proxy.go

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "time"

    "github.com/tv42/httpunix"
)

func handleHTTP(w http.ResponseWriter, req *http.Request) {

    fmt.Printf("Requested : %s\n", req.URL.Path)

    u := &httpunix.Transport{
        DialTimeout:           100 * time.Millisecond,
        RequestTimeout:        1 * time.Second,
        ResponseHeaderTimeout: 1 * time.Second,
    }
    u.RegisterLocation("docker-socket", "/var/run/docker.sock")

    req.URL.Scheme = "http+unix"
    req.URL.Host = "docker-socket"

    resp, err := u.RoundTrip(req)

    if err != nil {
        http.Error(w, err.Error(), http.StatusServiceUnavailable)
        return
    }
    defer resp.Body.Close()
    copyHeader(w.Header(), resp.Header)
    w.WriteHeader(resp.StatusCode)
    io.Copy(w, resp.Body)
}
func copyHeader(dst, src http.Header) {
    for k, vv := range src {
        for _, v := range vv {
            dst.Add(k, v)
        }
    }
}
func main() {

    server := &http.Server{
        Addr:    ":8888",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { handleHTTP(w, r) }),
    }

    log.Fatal(server.ListenAndServe())
}

https://github.com/ben-lab/blog-material/blob/master/golang-reverse-proxy-2/reverse-proxy.go

Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
0
0
929
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот, можете скопировать логику из моего следующего маленького проекта.

https://github.com/alessiosavi/StreamingServer/blob/0f65dbfc77f667777d3047fa1a6b1a2cbd8aaf26/auth/authutils.go

В первую очередь вам нужен сервер для хранения пользователей (я использовал Redis).

Чем вам нужно 3 функции для пользователя

  • ЛогинПользователь
  • РегистрацияПользователь
  • Удалить пользователя

На этапе входа/регистрации вы создаете файл cookie, хэширующий имя пользователя/пароль, и устанавливаете файл cookie в таблицу Redis.

Затем вы проверяете каждый раз, когда вызывается API.

Не стесняйтесь копировать код, который вам нужен.

Открывайте тему, если что-то не понятно.

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

anwar ul hasan 11.12.2020 04:08
Ответ принят как подходящий

Вы можете получить доступ к базовым значениям заголовка аутентификации, вызвав BasicAuth() на вашем

req *http.Request object

нравиться:

user, pass, _ := req.BasicAuth()

Затем сравните пользователя и перейдите со статическими значениями, которые у вас есть.

https://golang.org/pkg/net/http/#Request.BasicAuth

Обновлять:

func handleHTTP(w http.ResponseWriter, req *http.Request) {
    user, pass, _ := req.BasicAuth()
    if user != "muuser" || pass != "mysecret" {
      // you have to import "errors"
      http.Error(w, errors.New("not authoized!!"), http. StatusUnauthorized)
        return
    }
    fmt.Printf("Requested : %s\n", req.URL.Path)

    u := &httpunix.Transport{
        DialTimeout:           100 * time.Millisecond,
        RequestTimeout:        1 * time.Second,
        ResponseHeaderTimeout: 1 * time.Second,
    }
    u.RegisterLocation("docker-socket", "/var/run/docker.sock")

    req.URL.Scheme = "http+unix"
    req.URL.Host = "docker-socket"

    resp, err := u.RoundTrip(req)

    if err != nil {
        http.Error(w, err.Error(), http.StatusServiceUnavailable)
        return
    }
    defer resp.Body.Close()
    copyHeader(w.Header(), resp.Header)
    w.WriteHeader(resp.StatusCode)
    io.Copy(w, resp.Body)
}

не могли бы вы поделиться тем, как вызвать BasicAuth из объекта re *http.Request, поскольку я пытался посмотреть пример кода в Google, но не смог заставить его работать. заранее спасибо

anwar ul hasan 11.12.2020 04:12

Обновлен мой ответ, чтобы показать, как это сделать в вашем коде. Пожалуйста, не нужно импортировать "ошибки"

gipsy 11.12.2020 04:44

импортированные «ошибки», но не удалось выполнить сборку из-за следующей ошибки: reverse-proxy.go:17:31: невозможно использовать errors.New («не авторизовано!!») (ошибка типа) в качестве строки типа в аргументе для http.Error

anwar ul hasan 11.12.2020 12:27

это сработало как шарм, большое спасибо за помощь, приятель. Просто пришлось изменить: http.Error(w, errors.New("не авторизовано!!"), http.StatusUnauthorized) на http.Error(w, errors.New("не авторизовано!!").Error(), http.StatusUnauthorized)

anwar ul hasan 11.12.2020 13:05

Нужна еще одна помощь, не могли бы вы подсказать мне, как подключиться с помощью клиента Docker? Он отлично работает с curl, но не работает с клиентом docker. Я пробовал это, используя вход в докер, но я думаю, что получаю несанкционированную ошибку 401. Не могли бы вы помочь мне с этим тоже? Например, как я могу добавить учетные данные для этой команды? докер -H=127.0.0.1:8888 контейнер лс

anwar ul hasan 16.12.2020 16:54

Может попробовать -H=имя пользователя:пароль@127.0.0.1:8888

gipsy 19.12.2020 21:46

Другие вопросы по теме