write www-authenticate and delegate to reva

This commit is contained in:
A.Unger
2020-12-01 16:57:36 +01:00
parent d82f485604
commit 348c54f2e7
7 changed files with 67 additions and 23 deletions
+38 -15
View File
@@ -3,12 +3,32 @@ package middleware
import (
"fmt"
"net/http"
"strings"
"time"
)
// Authentication is a higher level authentication middleware.
var SupportedAuthStrategies []string
type statusRecorder struct {
http.ResponseWriter
status int
}
func (rec *statusRecorder) WriteHeader(code int) {
rec.status = code
rec.ResponseWriter.WriteHeader(code)
}
// Authentication is a higher order authentication middleware.
func Authentication(opts ...Option) func(next http.Handler) http.Handler {
options := newOptions(opts...)
if options.OIDCIss != "" {
SupportedAuthStrategies = append(SupportedAuthStrategies, "bearer")
}
if options.EnableBasicAuth {
SupportedAuthStrategies = append(SupportedAuthStrategies, "basic")
}
oidc := OIDCAuth(
Logger(options.Logger),
@@ -28,21 +48,24 @@ func Authentication(opts ...Option) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// here we multiplex depending on the use agent
userAgent := r.Header.Get("User-Agent")
fmt.Printf("\n\nUser-Agent:\t%s\n\n", userAgent)
switch userAgent {
case "a":
oidc(next).ServeHTTP(w, r)
return
case "b":
basic(next).ServeHTTP(w, r)
return
default:
oidc(next).ServeHTTP(w, r)
basic(next).ServeHTTP(w, r)
return
if options.OIDCIss != "" && options.EnableBasicAuth {
oidc(basic(next)).ServeHTTP(w, r)
}
if options.OIDCIss != "" && !options.EnableBasicAuth {
oidc(next).ServeHTTP(w, r)
}
if options.OIDCIss == "" && options.EnableBasicAuth {
basic(next).ServeHTTP(w, r)
}
})
}
}
func writeSupportedAuthenticateHeader(w http.ResponseWriter, r *http.Request) {
for i := 0; i < len(SupportedAuthStrategies); i++ {
w.Header().Add("WWW-Authenticate", fmt.Sprintf("%v realm=\"%s\", charset=\"UTF-8\"", strings.Title(SupportedAuthStrategies[i]), r.Host))
}
}
+8 -3
View File
@@ -32,15 +32,18 @@ func BasicAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, req *http.Request) {
if h.isPublicLink(req) || !h.isBasicAuth(req) {
// if we want to prevent duplicated Www-Authenticate headers coming from Reva consider using w.Header().Del("Www-Authenticate")
// but this will require the proxy being aware of endpoints which authentication fallback to Reva.
if !h.isPublicLink(req) {
w.Header().Add("Www-Authenticate", fmt.Sprintf("%v realm=\"%s\", charset=\"UTF-8\"", "Basic", req.Host))
}
next.ServeHTTP(w, req)
return
}
account, ok := h.getAccount(req)
if !ok {
// TODO need correct hostname
w.Header().Add("WWW-Authenticate", "Basic realm=\"Access to localhost\", charset=\"UTF-8\"")
w.Header().Add("Www-Authenticate", fmt.Sprintf("%v realm=\"%s\", charset=\"UTF-8\"", "Basic", req.Host))
w.WriteHeader(http.StatusUnauthorized)
return
}
@@ -50,6 +53,8 @@ func BasicAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
Iss: oidcIss,
}
fmt.Printf("\n\nHGAHAHAHA\n\n")
next.ServeHTTP(w, req.WithContext(oidc.NewContext(req.Context(), claims)))
},
)
+11 -4
View File
@@ -3,6 +3,7 @@ package middleware
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
@@ -37,11 +38,17 @@ func OIDCAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// there is no bearer token on the request,
if !h.shouldServe(req) {
// TODO need correct hostname
w.Header().Add("WWW-Authenticate", "Bearer realm=\"Access to localhost\", charset=\"UTF-8\"")
//w.WriteHeader(http.StatusUnauthorized)
//next.ServeHTTP(w, req)
// oidc supported but token not present, add header and handover to the next middleware.
// TODO for this logic to work and we don't return superfluous Www-Authenticate headers we would need to
// add Www-Authenticate only on selected endpoints, because Reva won't cleanup already written headers.
// this means that requests such as:
// curl -v -k -u admin:admin -H "depth: 0" -X PROPFIND https://localhost:9200/remote.php/dav/files | xmllint --format -
// even when succeeding, will contain a Www-Authenticate header.
w.Header().Add("Www-Authenticate", fmt.Sprintf("%v realm=\"%s\", charset=\"UTF-8\"", "Bearer", req.Host))
next.ServeHTTP(w, req)
return
}