mirror of
https://github.com/openfaas/faas.git
synced 2025-06-21 22:33:23 +00:00
Add basic auth plugin
This plugin can be tested as a stand-alone Golang app, or deployed as a Docker image with the following image: openfaas/basic-auth-plugin:0.1.0 Signed-off-by: Alex Ellis <alexellis2@gmail.com>
This commit is contained in:
13
auth/README.md
Normal file
13
auth/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
auth plugins
|
||||
============
|
||||
|
||||
Auth plugins must implement request checking on a HTTP port and path such as `:8080/validate`.
|
||||
|
||||
* Valid requests: return 2xx
|
||||
* Invalid requests: return non 2xx
|
||||
|
||||
It is up to the developer to pick whether a request body is required for validation. For strategies such as [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication), headers are sufficient.
|
||||
|
||||
Plugins available:
|
||||
|
||||
* [basic-auth](./basic-auth/)
|
1
auth/basic-auth/.gitignore
vendored
Normal file
1
auth/basic-auth/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
basic-auth*
|
26
auth/basic-auth/Dockerfile
Normal file
26
auth/basic-auth/Dockerfile
Normal file
@ -0,0 +1,26 @@
|
||||
FROM golang:1.10.4-alpine3.8 as build
|
||||
|
||||
RUN mkdir -p /go/src/handler
|
||||
WORKDIR /go/src/handler
|
||||
COPY . .
|
||||
|
||||
RUN CGO_ENABLED=0 GOOS=linux \
|
||||
go build --ldflags "-s -w" -a -installsuffix cgo -o handler . && \
|
||||
go test $(go list ./... | grep -v /vendor/) -cover
|
||||
|
||||
FROM alpine:3.9
|
||||
# Add non root user and certs
|
||||
RUN apk --no-cache add ca-certificates \
|
||||
&& addgroup -S app && adduser -S -g app app \
|
||||
&& mkdir -p /home/app \
|
||||
&& chown app /home/app
|
||||
|
||||
WORKDIR /home/app
|
||||
|
||||
COPY --from=build /go/src/handler/handler .
|
||||
|
||||
RUN chown -R app /home/app
|
||||
|
||||
USER app
|
||||
|
||||
CMD ["/go/src/handler/handler"]
|
17
auth/basic-auth/Gopkg.lock
generated
Normal file
17
auth/basic-auth/Gopkg.lock
generated
Normal file
@ -0,0 +1,17 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:deb76da5396c9f641ddea9ca79e31a14bdb09c787cdfda90488768b7539b1fd6"
|
||||
name = "github.com/openfaas/faas-provider"
|
||||
packages = ["auth"]
|
||||
pruneopts = "UT"
|
||||
revision = "6a76a052deb12fd94b373c082963d8a8ad44d4d1"
|
||||
version = "0.9.0"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = ["github.com/openfaas/faas-provider/auth"]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
34
auth/basic-auth/Gopkg.toml
Normal file
34
auth/basic-auth/Gopkg.toml
Normal file
@ -0,0 +1,34 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/openfaas/faas-provider"
|
||||
version = "0.9.0"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
6
auth/basic-auth/README.md
Normal file
6
auth/basic-auth/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
basic-auth
|
||||
============
|
||||
|
||||
This component provides plug-in authentication for the OpenFaaS gateway using basic authentication secrets.
|
||||
|
||||
Wikipedia: [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication)
|
68
auth/basic-auth/main.go
Normal file
68
auth/basic-auth/main.go
Normal file
@ -0,0 +1,68 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/openfaas/faas-provider/auth"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
port := 8080
|
||||
|
||||
if val, ok := os.LookupEnv("port"); ok {
|
||||
intOut, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, fmt.Sprintf("value of `port`: %s, not a valid port", val)))
|
||||
}
|
||||
port = intOut
|
||||
}
|
||||
|
||||
s := &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", port),
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 5 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20, // Max header of 1MB
|
||||
}
|
||||
|
||||
credentialsReader := auth.ReadBasicAuthFromDisk{
|
||||
SecretMountPath: os.Getenv("secret_mount_path"),
|
||||
}
|
||||
|
||||
credentials, err := credentialsReader.Read()
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "unable to read basic auth credentials, check `secret_mount_path`"))
|
||||
}
|
||||
|
||||
authHandler := auth.DecorateWithBasicAuth(func(w http.ResponseWriter, r *http.Request) {
|
||||
}, credentials)
|
||||
http.HandleFunc("/validate", makeLogger(authHandler))
|
||||
|
||||
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
log.Printf("Listening on: %d\n", port)
|
||||
log.Fatal(s.ListenAndServe())
|
||||
}
|
||||
|
||||
func makeLogger(next http.Handler) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
next.ServeHTTP(rr, r)
|
||||
log.Printf("Validated request %d.\n", rr.Code)
|
||||
|
||||
w.WriteHeader(rr.Code)
|
||||
if rr.Body != nil {
|
||||
w.Write(rr.Body.Bytes())
|
||||
}
|
||||
}
|
||||
}
|
21
auth/basic-auth/vendor/github.com/openfaas/faas-provider/LICENSE
generated
vendored
Normal file
21
auth/basic-auth/vendor/github.com/openfaas/faas-provider/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Alex Ellis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
26
auth/basic-auth/vendor/github.com/openfaas/faas-provider/auth/basic_auth.go
generated
vendored
Normal file
26
auth/basic-auth/vendor/github.com/openfaas/faas-provider/auth/basic_auth.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// DecorateWithBasicAuth enforces basic auth as a middleware with given credentials
|
||||
func DecorateWithBasicAuth(next http.HandlerFunc, credentials *BasicAuthCredentials) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
user, password, ok := r.BasicAuth()
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||
|
||||
if !ok || !(credentials.Password == password && user == credentials.User) {
|
||||
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("invalid credentials"))
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
52
auth/basic-auth/vendor/github.com/openfaas/faas-provider/auth/credentials.go
generated
vendored
Normal file
52
auth/basic-auth/vendor/github.com/openfaas/faas-provider/auth/credentials.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BasicAuthCredentials for credentials
|
||||
type BasicAuthCredentials struct {
|
||||
User string
|
||||
Password string
|
||||
}
|
||||
|
||||
type ReadBasicAuth interface {
|
||||
Read() (error, *BasicAuthCredentials)
|
||||
}
|
||||
|
||||
type ReadBasicAuthFromDisk struct {
|
||||
SecretMountPath string
|
||||
}
|
||||
|
||||
func (r *ReadBasicAuthFromDisk) Read() (*BasicAuthCredentials, error) {
|
||||
var credentials *BasicAuthCredentials
|
||||
|
||||
if len(r.SecretMountPath) == 0 {
|
||||
return nil, fmt.Errorf("invalid SecretMountPath specified for reading secrets")
|
||||
}
|
||||
|
||||
userPath := path.Join(r.SecretMountPath, "basic-auth-user")
|
||||
user, userErr := ioutil.ReadFile(userPath)
|
||||
if userErr != nil {
|
||||
return nil, fmt.Errorf("unable to load %s", userPath)
|
||||
}
|
||||
|
||||
userPassword := path.Join(r.SecretMountPath, "basic-auth-password")
|
||||
password, passErr := ioutil.ReadFile(userPassword)
|
||||
if passErr != nil {
|
||||
return nil, fmt.Errorf("Unable to load %s", userPassword)
|
||||
}
|
||||
|
||||
credentials = &BasicAuthCredentials{
|
||||
User: strings.TrimSpace(string(user)),
|
||||
Password: strings.TrimSpace(string(password)),
|
||||
}
|
||||
|
||||
return credentials, nil
|
||||
}
|
Reference in New Issue
Block a user