1
0
Files
docker-auth/server.go
2023-08-25 11:05:36 +08:00

91 lines
2.2 KiB
Go

package main
import (
"crypto/tls"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/handlers"
)
var (
addr string
ti TokenIssuer
)
func main() {
flag.StringVar(&addr, "addr", ":5001", "address")
flag.StringVar(&ti.Issuer, "issuer", "omnibus-gitlab-issuer", "issuer name")
flag.StringVar(&ti.Audience, "audience", "docker", "audience name")
flag.Int64Var(&ti.Expiration, "expires", 900, "expiration")
flag.Parse()
log.SetFlags(log.LstdFlags | log.Lshortfile)
cert, err := tls.LoadX509KeyPair("auth.crt", "auth.key")
if err != nil {
log.Fatal(err)
}
ti.SigningKey = cert.PrivateKey
mux := http.NewServeMux()
mux.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
var resp struct {
Token string `json:"access_token"`
RefreshToken string `json:"refresh_token,omitempty"`
ExpiresIn int64 `json:"expires_in,omitempty"`
}
user, _, ok := r.BasicAuth()
if !ok {
w.Header().Set("WWW-Authenticate", "Basic realm=Restricted")
w.WriteHeader(http.StatusUnauthorized)
return
}
authRequest := ResolveScopeList(r.URL.Query().Get("scope"))
if len(authRequest) == 0 {
// Authentication-only request ("docker login"), pass through.
resp.Token, _ = ti.CreateJWT(user, authRequest)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(&resp)
return
}
authResult, err := Authorized(user, authRequest)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
if resp.Token, err = ti.CreateJWT(user, authResult); err != nil {
log.Printf("CreateJWT %v", err)
w.WriteHeader(http.StatusUnauthorized)
return
}
resp.ExpiresIn = ti.Expiration
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(&resp)
})
h := handlers.CustomLoggingHandler(os.Stdout, mux, func(w io.Writer, p handlers.LogFormatterParams) {
fmt.Fprintf(w, "%s %s %d %s %d %s (%s)\n", p.TimeStamp.Format("2006/01/02 15:04:05"),
p.Request.Method, p.StatusCode, p.URL.RequestURI(), p.Size,
p.Request.RemoteAddr, time.Since(p.TimeStamp))
})
log.Fatal(http.ListenAndServe(addr, h))
}
func Authorized(user string, actions []ResourceActions) ([]ResourceActions, error) {
return actions, nil
}