authorization middleware

This commit is contained in:
boyska 2018-09-30 14:05:25 +02:00
parent c1f0e9da3e
commit bbd3cdc721
6 changed files with 99 additions and 8 deletions

6
.gitignore vendored
View file

@ -1,3 +1,3 @@
vendor /vendor
panelcli /panelcli
userpanel /userpanel

View file

@ -2,7 +2,7 @@ FROM golang:1.11-alpine as builder
RUN apk --no-cache add git gcc musl-dev RUN apk --no-cache add git gcc musl-dev
WORKDIR /go/src/git.lattuga.net/boyska/feedpanel/ WORKDIR /go/src/git.lattuga.net/boyska/feedpanel/
COPY ./ /go/src/git.lattuga.net/boyska/feedpanel/ COPY ./ /go/src/git.lattuga.net/boyska/feedpanel/
RUN CGO_ENABLED=0 GOOS=linux go install -v ./... RUN CGO_ENABLED=0 GOOS=linux go install ./...
FROM busybox FROM busybox
WORKDIR /usr/bin/ WORKDIR /usr/bin/

View file

@ -3,13 +3,25 @@ package main
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/urfave/negroni"
) )
func main() { func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { mux := http.NewServeMux()
w.WriteHeader(501) mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Nothing has been implemented. Just cross your fingers.\n") user := r.Context().Value(keyUser)
if user == nil {
panic("Authentication middleware failed!")
}
w.WriteHeader(200)
fmt.Fprintf(w, "Hello, %s\n", user)
}) })
http.ListenAndServe(":8000", nil) ha := HeaderAuth{AllowedNames: []string{"feedati-fe"}, RequireUser: true}
n := negroni.New(negroni.NewRecovery(), negroni.NewLogger(), ha)
n.UseHandler(mux)
addr := ":8000"
fmt.Println("Listening on", addr)
http.ListenAndServe(addr, n)
} }

View file

@ -0,0 +1,76 @@
package main
import (
"context"
"net"
"net/http"
)
type ctxKey int
const (
keyUser = iota
)
//HeaderAuth is a Negroni-compatible Middleware
type HeaderAuth struct {
AllowedNames []string
AllowedIPs []net.IP
RequireUser bool
}
func _getSourceIP(req *http.Request) (net.IP, error) {
ip, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
return net.IP{}, err
}
userIP := net.ParseIP(ip)
if userIP == nil {
return net.IP{}, err
}
return userIP, nil
}
func (ha HeaderAuth) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
srcIP, err := _getSourceIP(r)
if err != nil {
rw.WriteHeader(501)
return
}
found := false
if len(ha.AllowedNames) == 0 && len(ha.AllowedIPs) == 0 {
found = true
}
if !found && len(ha.AllowedIPs) > 0 {
for _, allowedIP := range ha.AllowedIPs {
if allowedIP.Equal(srcIP) {
found = true
break
}
}
}
if !found && len(ha.AllowedNames) > 0 {
for _, name := range ha.AllowedNames {
nameips, err := net.LookupIP(name)
if err != nil {
continue
}
for _, allowedIP := range nameips {
if allowedIP.Equal(srcIP) {
found = true
break
}
}
}
}
user := r.Header.Get("X-Forwarded-User")
if !found || (ha.RequireUser && user == "") {
rw.WriteHeader(http.StatusUnauthorized)
return
}
ctx := r.Context()
ctx = context.WithValue(ctx, keyUser, user)
next(rw, r.WithContext(ctx))
return
}

1
go.mod
View file

@ -7,6 +7,7 @@ require (
github.com/kr/pretty v0.1.0 // indirect github.com/kr/pretty v0.1.0 // indirect
github.com/onsi/gomega v1.4.2 // indirect github.com/onsi/gomega v1.4.2 // indirect
github.com/pkg/errors v0.8.0 github.com/pkg/errors v0.8.0
github.com/urfave/negroni v1.0.0
github.com/vmihailenco/sasl v0.0.0-20180913092844-58bfd2104008 // indirect github.com/vmihailenco/sasl v0.0.0-20180913092844-58bfd2104008 // indirect
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect

2
go.sum
View file

@ -21,6 +21,8 @@ github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/vmihailenco/sasl v0.0.0-20180913092844-58bfd2104008 h1:QvUVTr/4BCSyk46CIcYxDh5qQJbV65nWcMlv6whzm1Y= github.com/vmihailenco/sasl v0.0.0-20180913092844-58bfd2104008 h1:QvUVTr/4BCSyk46CIcYxDh5qQJbV65nWcMlv6whzm1Y=
github.com/vmihailenco/sasl v0.0.0-20180913092844-58bfd2104008/go.mod h1:PL3B2VvrDEUUKvagXPKVvvmulVvRE2DWIJovqpdpHwI= github.com/vmihailenco/sasl v0.0.0-20180913092844-58bfd2104008/go.mod h1:PL3B2VvrDEUUKvagXPKVvvmulVvRE2DWIJovqpdpHwI=
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b h1:2b9XGzhjiYsYPnKXoEfL7klWZQIt8IfyRCz62gCqqlQ= golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b h1:2b9XGzhjiYsYPnKXoEfL7klWZQIt8IfyRCz62gCqqlQ=