123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- package dynamicproxy
- import (
- "errors"
- "net/http"
- "strings"
- "imuslab.com/zoraxy/mod/auth"
- )
- /*
- authProviders.go
- This script handle authentication providers
- */
- /*
- Central Authentication Provider Router
- This function will route the request to the correct authentication provider
- if the return value is true, do not continue to the next handler
- handleAuthProviderRouting takes in 4 parameters:
- - sep: the ProxyEndpoint object
- - w: the http.ResponseWriter object
- - r: the http.Request object
- - h: the ProxyHandler object
- and return a boolean indicate if the request is written to http.ResponseWriter
- - true: the request is handled, do not write to http.ResponseWriter
- - false: the request is not handled (usually means auth ok), continue to the next handler
- */
- func handleAuthProviderRouting(sep *ProxyEndpoint, w http.ResponseWriter, r *http.Request, h *ProxyHandler) bool {
- if sep.AuthenticationProvider.AuthMethod == AuthMethodBasic {
- err := h.handleBasicAuthRouting(w, r, sep)
- if err != nil {
- h.Parent.Option.Logger.LogHTTPRequest(r, "host", 401)
- return true
- }
- } else if sep.AuthenticationProvider.AuthMethod == AuthMethodAuthelia {
- err := h.handleAutheliaAuth(w, r)
- if err != nil {
- h.Parent.Option.Logger.LogHTTPRequest(r, "host", 401)
- return true
- }
- }
- //No authentication provider, do not need to handle
- return false
- }
- /* Basic Auth */
- func (h *ProxyHandler) handleBasicAuthRouting(w http.ResponseWriter, r *http.Request, pe *ProxyEndpoint) error {
- err := handleBasicAuth(w, r, pe)
- if err != nil {
- h.Parent.logRequest(r, false, 401, "host", r.URL.Hostname())
- }
- return err
- }
- // Handle basic auth logic
- // do not write to http.ResponseWriter if err return is not nil (already handled by this function)
- func handleBasicAuth(w http.ResponseWriter, r *http.Request, pe *ProxyEndpoint) error {
- if len(pe.AuthenticationProvider.BasicAuthExceptionRules) > 0 {
- //Check if the current path matches the exception rules
- for _, exceptionRule := range pe.AuthenticationProvider.BasicAuthExceptionRules {
- if strings.HasPrefix(r.RequestURI, exceptionRule.PathPrefix) {
- //This path is excluded from basic auth
- return nil
- }
- }
- }
- u, p, ok := r.BasicAuth()
- if !ok {
- w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
- w.WriteHeader(401)
- return errors.New("unauthorized")
- }
- //Check for the credentials to see if there is one matching
- hashedPassword := auth.Hash(p)
- matchingFound := false
- for _, cred := range pe.AuthenticationProvider.BasicAuthCredentials {
- if u == cred.Username && hashedPassword == cred.PasswordHash {
- matchingFound = true
- //Set the X-Remote-User header
- r.Header.Set("X-Remote-User", u)
- break
- }
- }
- if !matchingFound {
- w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
- w.WriteHeader(401)
- return errors.New("unauthorized")
- }
- return nil
- }
- /* Authelia */
- // Handle authelia auth routing
- func (h *ProxyHandler) handleAutheliaAuth(w http.ResponseWriter, r *http.Request) error {
- return h.Parent.Option.AutheliaRouter.HandleAutheliaAuth(w, r)
- }
|