mirror of https://github.com/portainer/portainer
66 lines
1.7 KiB
Go
66 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/dgrijalva/jwt-go"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
func addMiddleware(h http.Handler, middleware ...func(http.Handler) http.Handler) http.Handler {
|
|
for _, mw := range middleware {
|
|
h = mw(h)
|
|
}
|
|
return h
|
|
}
|
|
|
|
// authenticate provides Authentication middleware for handlers
|
|
func (api *api) authenticate(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
var token string
|
|
|
|
// Get token from the Authorization header
|
|
// format: Authorization: Bearer
|
|
tokens, ok := r.Header["Authorization"]
|
|
if ok && len(tokens) >= 1 {
|
|
token = tokens[0]
|
|
token = strings.TrimPrefix(token, "Bearer ")
|
|
}
|
|
|
|
if token == "" {
|
|
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
|
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
msg := fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
|
return nil, msg
|
|
}
|
|
return api.secret, nil
|
|
})
|
|
if err != nil {
|
|
http.Error(w, "Invalid JWT token", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
if parsedToken == nil || !parsedToken.Valid {
|
|
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// context.Set(r, "user", parsedToken)
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
})
|
|
}
|
|
|
|
// SecureHeaders adds secure headers to the API
|
|
func secureHeaders(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Add("X-Content-Type-Options", "nosniff")
|
|
w.Header().Add("X-Frame-Options", "DENY")
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|