简体   繁体   English

向基于 Go 的反向代理服务器添加基本身份验证

[英]Adding basic authentication to Go based reverse proxy server

I want to secure Docker daemon REST API using Go reverse proxy server.我想保护 Docker 守护进程 REST API 使用 Z5F075AE3E1F9D038296F1 反向代理服务器。 I found this article very relevant.我发现这篇文章非常相关。 I have never used Go so not sure how to implement basic authentication to this with static username and password.我从来没有使用过 Go 所以不确定如何使用 static 用户名和密码来实现基本身份验证。 I tried all possible ways i happened to find over Google but none worked for me.我尝试了我碰巧在谷歌上找到的所有可能的方法,但没有一个对我有用。

Could some please help adding static basicAuth authentication to following code so that request so that Docker daemon API is only reachable if the request includes username and password: https://github.com/ben-lab/blog-material/blob/master/golang-reverse-proxy-2/reverse-proxy.go Could some please help adding static basicAuth authentication to following code so that request so that Docker daemon API is only reachable if the request includes username and password: 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 https://github.com/ben-lab/blog-material/blob/master/golang-reverse-proxy-2/reverse-proxy.go

Here you are, you can copy the logic from my following little project.在这里,您可以从我的以下小项目中复制逻辑。

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

In first instance you need a server for store the users (I've used Redis).首先,您需要一个服务器来存储用户(我使用过 Redis)。

Than you need 3 function for the user比用户需要 3 个 function

  • LoginUser登录用户
  • RegisterUser注册用户
  • DeleteUser删除用户

During the login/register phase, you generate a cookie hashing username/password and setting the cookie into a Redis table在登录/注册阶段,您生成一个 cookie 散列用户名/密码并将 cookie 设置到 Redis 表中

Than you verify every time that an API is called.比您每次调用 API 时都要验证。

Feel free to copy the code that you need.随意复制您需要的代码。

Open an issue if something is not well understandable.如果某些事情不能很好理解,请打开一个问题。

You can access the basic auth header values by calling BasicAuth() on your您可以通过调用BasicAuth()在您的

req *http.Request object

like:喜欢:

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

Then compare user and pass with the static values you have.然后比较用户并通过您拥有的 static 值。

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

Update:更新:

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)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM