feat: forward auth

This adds basic support for forwarded authentication similar to caddy and traefik. This replaces Authelia SSO as it effectively covers exactly the same use cases.
This commit is contained in:
James Elliott
2025-04-21 10:50:37 +10:00
parent 0e5550487e
commit 8f046a0b47
14 changed files with 433 additions and 490 deletions

View File

@@ -1,164 +0,0 @@
package authelia
import (
"encoding/json"
"errors"
"net"
"net/http"
"net/url"
"strings"
"imuslab.com/zoraxy/mod/database"
"imuslab.com/zoraxy/mod/info/logger"
"imuslab.com/zoraxy/mod/utils"
)
type AutheliaRouterOptions struct {
UseHTTPS bool //If the Authelia server is using HTTPS
AutheliaURL string //The URL of the Authelia server
Logger *logger.Logger
Database *database.Database
}
type AutheliaRouter struct {
options *AutheliaRouterOptions
}
// NewAutheliaRouter creates a new AutheliaRouter object
func NewAutheliaRouter(options *AutheliaRouterOptions) *AutheliaRouter {
options.Database.NewTable("authelia")
//Read settings from database, if exists
options.Database.Read("authelia", "autheliaURL", &options.AutheliaURL)
options.Database.Read("authelia", "useHTTPS", &options.UseHTTPS)
return &AutheliaRouter{
options: options,
}
}
// HandleSetAutheliaURLAndHTTPS is the internal handler for setting the Authelia URL and HTTPS
func (ar *AutheliaRouter) HandleSetAutheliaURLAndHTTPS(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
//Return the current settings
js, _ := json.Marshal(map[string]interface{}{
"useHTTPS": ar.options.UseHTTPS,
"autheliaURL": ar.options.AutheliaURL,
})
utils.SendJSONResponse(w, string(js))
return
} else if r.Method == http.MethodPost {
//Update the settings
autheliaURL, err := utils.PostPara(r, "autheliaURL")
if err != nil {
utils.SendErrorResponse(w, "autheliaURL not found")
return
}
useHTTPS, err := utils.PostBool(r, "useHTTPS")
if err != nil {
useHTTPS = false
}
//Write changes to runtime
ar.options.AutheliaURL = autheliaURL
ar.options.UseHTTPS = useHTTPS
//Write changes to database
ar.options.Database.Write("authelia", "autheliaURL", autheliaURL)
ar.options.Database.Write("authelia", "useHTTPS", useHTTPS)
utils.SendOK(w)
} else {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
}
// handleAutheliaAuth is the internal handler for Authelia authentication
// Set useHTTPS to true if your authelia server is using HTTPS
// Set autheliaURL to the URL of the Authelia server, e.g. authelia.example.com
func (ar *AutheliaRouter) HandleAutheliaAuth(w http.ResponseWriter, r *http.Request) error {
client := &http.Client{}
if ar.options.AutheliaURL == "" {
ar.options.Logger.PrintAndLog("Authelia", "Authelia URL not set", nil)
w.WriteHeader(500)
w.Write([]byte("500 - Internal Server Error"))
return errors.New("authelia URL not set")
}
protocol := "http"
if ar.options.UseHTTPS {
protocol = "https"
}
autheliaURL := &url.URL{
Scheme: protocol,
Host: ar.options.AutheliaURL,
}
//Make a request to Authelia to verify the request
req, err := http.NewRequest("POST", autheliaURL.JoinPath("api", "verify").String(), nil)
if err != nil {
ar.options.Logger.PrintAndLog("Authelia", "Unable to create request", err)
w.WriteHeader(401)
return errors.New("unauthorized")
}
originalURL := rOriginalHeaders(r, req)
// Copy cookies from the incoming request
for _, cookie := range r.Cookies() {
req.AddCookie(cookie)
}
// Making the verification request
resp, err := client.Do(req)
if err != nil {
ar.options.Logger.PrintAndLog("Authelia", "Unable to verify", err)
w.WriteHeader(401)
return errors.New("unauthorized")
}
if resp.StatusCode != 200 {
redirectURL := autheliaURL.JoinPath()
query := redirectURL.Query()
query.Set("rd", originalURL.String())
query.Set("rm", r.Method)
http.Redirect(w, r, redirectURL.String(), http.StatusSeeOther)
return errors.New("unauthorized")
}
return nil
}
func rOriginalHeaders(r, req *http.Request) *url.URL {
if r.RemoteAddr != "" {
before, _, _ := strings.Cut(r.RemoteAddr, ":")
if ip := net.ParseIP(before); ip != nil {
req.Header.Set("X-Forwarded-For", ip.String())
}
}
originalURL := &url.URL{
Scheme: "http",
Host: r.Host,
Path: r.URL.Path,
RawPath: r.URL.RawPath,
}
if r.TLS != nil {
originalURL.Scheme = "https"
}
req.Header.Add("X-Forwarded-Method", r.Method)
req.Header.Add("X-Original-URL", originalURL.String())
return originalURL
}

View File

@@ -1,169 +0,0 @@
package authentik
import (
"encoding/json"
"errors"
"io"
"net/http"
"net/url"
"strings"
"imuslab.com/zoraxy/mod/database"
"imuslab.com/zoraxy/mod/info/logger"
"imuslab.com/zoraxy/mod/utils"
)
type AuthentikRouterOptions struct {
UseHTTPS bool //If the Authentik server is using HTTPS
AuthentikURL string //The URL of the Authentik server
Logger *logger.Logger
Database *database.Database
}
type AuthentikRouter struct {
options *AuthentikRouterOptions
}
// NewAuthentikRouter creates a new AuthentikRouter object
func NewAuthentikRouter(options *AuthentikRouterOptions) *AuthentikRouter {
options.Database.NewTable("authentik")
//Read settings from database, if exists
options.Database.Read("authentik", "authentikURL", &options.AuthentikURL)
options.Database.Read("authentik", "useHTTPS", &options.UseHTTPS)
return &AuthentikRouter{
options: options,
}
}
// HandleSetAuthentikURLAndHTTPS is the internal handler for setting the Authentik URL and HTTPS
func (ar *AuthentikRouter) HandleSetAuthentikURLAndHTTPS(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
//Return the current settings
js, _ := json.Marshal(map[string]interface{}{
"useHTTPS": ar.options.UseHTTPS,
"authentikURL": ar.options.AuthentikURL,
})
utils.SendJSONResponse(w, string(js))
return
} else if r.Method == http.MethodPost {
//Update the settings
AuthentikURL, err := utils.PostPara(r, "authentikURL")
if err != nil {
utils.SendErrorResponse(w, "authentikURL not found")
return
}
useHTTPS, err := utils.PostBool(r, "useHTTPS")
if err != nil {
useHTTPS = false
}
//Write changes to runtime
ar.options.AuthentikURL = AuthentikURL
ar.options.UseHTTPS = useHTTPS
//Write changes to database
ar.options.Database.Write("authentik", "authentikURL", AuthentikURL)
ar.options.Database.Write("authentik", "useHTTPS", useHTTPS)
utils.SendOK(w)
} else {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
}
// HandleAuthentikAuth is the internal handler for Authentik authentication
// Set useHTTPS to true if your Authentik server is using HTTPS
// Set AuthentikURL to the URL of the Authentik server, e.g. Authentik.example.com
func (ar *AuthentikRouter) HandleAuthentikAuth(w http.ResponseWriter, r *http.Request) error {
const outpostPrefix = "outpost.goauthentik.io"
client := &http.Client{}
if ar.options.AuthentikURL == "" {
ar.options.Logger.PrintAndLog("Authentik", "Authentik URL not set", nil)
w.WriteHeader(500)
w.Write([]byte("500 - Internal Server Error"))
return errors.New("authentik URL not set")
}
protocol := "http"
if ar.options.UseHTTPS {
protocol = "https"
}
authentikBaseURL := protocol + "://" + ar.options.AuthentikURL
//Remove tailing slash if any
authentikBaseURL = strings.TrimSuffix(authentikBaseURL, "/")
scheme := "http"
if r.TLS != nil {
scheme = "https"
}
reqUrl := scheme + "://" + r.Host + r.RequestURI
// Pass request to outpost if path matches outpost prefix
if reqPath := strings.TrimPrefix(r.URL.Path, "/"); strings.HasPrefix(reqPath, outpostPrefix) {
req, err := http.NewRequest(r.Method, authentikBaseURL+r.RequestURI, r.Body)
if err != nil {
ar.options.Logger.PrintAndLog("Authentik", "Unable to create request", err)
w.WriteHeader(401)
return errors.New("unauthorized")
}
req.Header.Set("X-Original-URL", reqUrl)
req.Header.Set("Host", r.Host)
for _, cookie := range r.Cookies() {
req.AddCookie(cookie)
}
if resp, err := client.Do(req); err != nil {
ar.options.Logger.PrintAndLog("Authentik", "Unable to pass request to Authentik outpost", err)
w.WriteHeader(http.StatusInternalServerError)
return errors.New("internal server error")
} else {
defer resp.Body.Close()
for k := range resp.Header {
w.Header().Set(k, resp.Header.Get(k))
}
w.WriteHeader(resp.StatusCode)
if _, err = io.Copy(w, resp.Body); err != nil {
ar.options.Logger.PrintAndLog("Authentik", "Unable to pass Authentik outpost response to client", err)
w.WriteHeader(http.StatusInternalServerError)
return errors.New("internal server error")
}
}
return nil
}
//Make a request to Authentik to verify the request
req, err := http.NewRequest(http.MethodGet, authentikBaseURL+"/"+outpostPrefix+"/auth/nginx", nil)
if err != nil {
ar.options.Logger.PrintAndLog("Authentik", "Unable to create request", err)
w.WriteHeader(401)
return errors.New("unauthorized")
}
req.Header.Set("X-Original-URL", reqUrl)
// Copy cookies from the incoming request
for _, cookie := range r.Cookies() {
req.AddCookie(cookie)
}
// Making the verification request
resp, err := client.Do(req)
if err != nil {
ar.options.Logger.PrintAndLog("Authentik", "Unable to verify", err)
w.WriteHeader(401)
return errors.New("unauthorized")
}
if resp.StatusCode != 200 {
redirectURL := authentikBaseURL + "/" + outpostPrefix + "/start?rd=" + url.QueryEscape(scheme+"://"+r.Host+r.URL.String())
http.Redirect(w, r, redirectURL, http.StatusSeeOther)
return errors.New("unauthorized")
}
return nil
}

View File

@@ -0,0 +1,44 @@
package forward
import "errors"
const (
LogTitle = "Forward Auth"
DatabaseTable = "auth_sso_forward"
DatabaseKeyAddress = "address"
DatabaseKeyResponseHeaders = "responseHeaders"
DatabaseKeyRequestExcludedCookies = "requestExcludedCookies"
HeaderXForwardedProto = "X-Forwarded-Proto"
HeaderXForwardedHost = "X-Forwarded-Host"
HeaderXForwardedFor = "X-Forwarded-For"
HeaderXForwardedURI = "X-Forwarded-URI"
HeaderXForwardedMethod = "X-Forwarded-Method"
HeaderCookie = "Cookie"
HeaderUpgrade = "Upgrade"
HeaderConnection = "Connection"
HeaderTransferEncoding = "Transfer-Encoding"
HeaderTE = "TE"
HeaderTrailers = "Trailers"
HeaderKeepAlive = "Keep-Alive"
)
var (
ErrInternalServerError = errors.New("internal server error")
ErrUnauthorized = errors.New("unauthorized")
)
var (
doNotCopyHeaders = []string{
HeaderUpgrade,
HeaderConnection,
HeaderTransferEncoding,
HeaderTE,
HeaderTrailers,
HeaderKeepAlive,
}
)

View File

@@ -0,0 +1,294 @@
package forward
import (
"encoding/json"
"io"
"net"
"net/http"
"strings"
"imuslab.com/zoraxy/mod/database"
"imuslab.com/zoraxy/mod/info/logger"
"imuslab.com/zoraxy/mod/utils"
)
type AuthRouterOptions struct {
// Address of the forward auth endpoint.
Address string
// ResponseHeaders is a list of headers to be copied from the response if provided by the forward auth endpoint to
// the request.
ResponseHeaders []string
// RequestExcludedCookies is a list of cookie keys that should be removed from every request sent to the upstream.
RequestExcludedCookies []string
Logger *logger.Logger
Database *database.Database
}
type AuthRouter struct {
client *http.Client
options *AuthRouterOptions
}
// NewAuthRouter creates a new AuthRouter object
func NewAuthRouter(options *AuthRouterOptions) *AuthRouter {
options.Database.NewTable(DatabaseTable)
//Read settings from database if available.
options.Database.Read(DatabaseTable, DatabaseKeyAddress, &options.Address)
responseHeaders, requestExcludedCookies := "", ""
options.Database.Read(DatabaseTable, DatabaseKeyResponseHeaders, responseHeaders)
options.Database.Read(DatabaseTable, DatabaseKeyRequestExcludedCookies, requestExcludedCookies)
options.ResponseHeaders = strings.Split(responseHeaders, ",")
options.RequestExcludedCookies = strings.Split(requestExcludedCookies, ",")
return &AuthRouter{
client: &http.Client{
CheckRedirect: func(r *http.Request, via []*http.Request) (err error) {
return http.ErrUseLastResponse
},
},
options: options,
}
}
// HandleAPIOptions is the internal handler for setting the options.
func (ar *AuthRouter) HandleAPIOptions(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
ar.handleOptionsGET(w, r)
case http.MethodPost:
ar.handleOptionsPOST(w, r)
default:
ar.handleOptionsMethodNotAllowed(w, r)
}
}
func (ar *AuthRouter) handleOptionsGET(w http.ResponseWriter, r *http.Request) {
js, _ := json.Marshal(map[string]interface{}{
DatabaseKeyAddress: ar.options.Address,
DatabaseKeyResponseHeaders: ar.options.ResponseHeaders,
DatabaseKeyRequestExcludedCookies: ar.options.RequestExcludedCookies,
})
utils.SendJSONResponse(w, string(js))
return
}
func (ar *AuthRouter) handleOptionsPOST(w http.ResponseWriter, r *http.Request) {
// Update the settings
address, err := utils.PostPara(r, DatabaseKeyAddress)
if err != nil {
utils.SendErrorResponse(w, "address not found")
return
}
// These are optional fields.
responseHeaders, _ := utils.PostPara(r, DatabaseKeyResponseHeaders)
requestExcludedCookies, _ := utils.PostPara(r, DatabaseKeyRequestExcludedCookies)
// Write changes to runtime
ar.options.Address = address
ar.options.ResponseHeaders = strings.Split(responseHeaders, ",")
ar.options.RequestExcludedCookies = strings.Split(requestExcludedCookies, ",")
// Write changes to database
ar.options.Database.Write(DatabaseTable, DatabaseKeyAddress, address)
ar.options.Database.Write(DatabaseTable, DatabaseKeyResponseHeaders, responseHeaders)
ar.options.Database.Write(DatabaseTable, DatabaseKeyRequestExcludedCookies, requestExcludedCookies)
utils.SendOK(w)
}
func (ar *AuthRouter) handleOptionsMethodNotAllowed(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
// HandleAuthProviderRouting is the internal handler for Forward Auth authentication.
func (ar *AuthRouter) HandleAuthProviderRouting(w http.ResponseWriter, r *http.Request) error {
if ar.options.Address == "" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
ar.options.Logger.PrintAndLog(LogTitle, "Address not set", nil)
return ErrInternalServerError
}
// Make a request to Authz Server to verify the request
req, err := http.NewRequest(http.MethodGet, ar.options.Address, nil)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
ar.options.Logger.PrintAndLog(LogTitle, "Unable to create request", err)
return ErrInternalServerError
}
// TODO: Add opt-in support for copying the request body to the forward auth request.
// TODO: Add support for customizing which headers are copied from the request to the forward auth request.
headerCopyExcluded(r.Header, req.Header, nil)
// TODO: Add support for upstream headers.
rSetForwardedHeaders(r, req)
// Make the Authz Request.
respForwarded, err := ar.client.Do(req)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
ar.options.Logger.PrintAndLog(LogTitle, "Unable to perform forwarded auth due to a request error", err)
return ErrInternalServerError
}
defer respForwarded.Body.Close()
body, err := io.ReadAll(respForwarded.Body)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
ar.options.Logger.PrintAndLog(LogTitle, "Unable to read response to forward auth request", err)
return ErrInternalServerError
}
// Responses within the 200-299 range are considered successful and allow the proxy to handle the request.
if respForwarded.StatusCode >= http.StatusOK && respForwarded.StatusCode < http.StatusMultipleChoices {
// TODO: Add support for copying response headers to the response (in the user agent), not just the request.
if len(ar.options.ResponseHeaders) != 0 {
// If the user has specified a list of cookies to be removed from the request, deterministically remove them.
headerCookieRedact(r, ar.options.RequestExcludedCookies)
}
// Copy specific user-specified headers from the response of the forward auth request to the request sent to the
// upstream server/next hop.
headerCopyIncluded(respForwarded.Header, w.Header(), ar.options.ResponseHeaders)
return nil
}
// Copy the response.
headerCopyExcluded(respForwarded.Header, w.Header(), nil)
w.WriteHeader(respForwarded.StatusCode)
if _, err = w.Write(body); err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
ar.options.Logger.PrintAndLog(LogTitle, "Unable to write response", err)
return ErrInternalServerError
}
return ErrUnauthorized
}
func scheme(r *http.Request) string {
if r.TLS != nil {
return "https"
}
return "http"
}
func headerCookieRedact(r *http.Request, excluded []string) {
original := r.Cookies()
if len(original) == 0 {
return
}
var cookies []string
for _, cookie := range original {
if stringInSlice(cookie.Name, excluded) {
continue
}
cookies = append(cookies, cookie.String())
}
r.Header.Set(HeaderCookie, strings.Join(cookies, "; "))
}
func headerCopyExcluded(original, destination http.Header, excludedHeaders []string) {
for key, values := range original {
// We should never copy the headers in the below list.
if stringInSliceFold(key, doNotCopyHeaders) {
continue
}
if stringInSliceFold(key, excludedHeaders) {
continue
}
destination[key] = append(destination[key], values...)
}
}
func headerCopyIncluded(original, destination http.Header, includedHeaders []string) {
for key, values := range original {
// We should never copy the headers in the below list, even if they're in the list provided by a user.
if stringInSliceFold(key, doNotCopyHeaders) {
continue
}
if !stringInSliceFold(key, includedHeaders) {
continue
}
destination[key] = append(destination[key], values...)
}
}
func stringInSlice(needle string, haystack []string) bool {
if len(haystack) == 0 {
return false
}
for _, v := range haystack {
if needle == v {
return true
}
}
return false
}
func stringInSliceFold(needle string, haystack []string) bool {
if len(haystack) == 0 {
return false
}
for _, v := range haystack {
if strings.EqualFold(needle, v) {
return true
}
}
return false
}
func rSetForwardedHeaders(r, req *http.Request) {
if r.RemoteAddr != "" {
before, _, _ := strings.Cut(r.RemoteAddr, ":")
if ip := net.ParseIP(before); ip != nil {
req.Header.Set(HeaderXForwardedFor, ip.String())
}
}
req.Header.Set(HeaderXForwardedMethod, r.Method)
req.Header.Set(HeaderXForwardedProto, scheme(r))
req.Header.Set(HeaderXForwardedHost, r.Host)
req.Header.Set(HeaderXForwardedURI, r.URL.Path)
}

View File

@@ -32,20 +32,16 @@ and return a boolean indicate if the request is written to http.ResponseWriter
*/
func handleAuthProviderRouting(sep *ProxyEndpoint, w http.ResponseWriter, r *http.Request, h *ProxyHandler) bool {
requestHostname := r.Host
if sep.AuthenticationProvider.AuthMethod == AuthMethodBasic {
switch sep.AuthenticationProvider.AuthMethod {
case AuthMethodBasic:
err := h.handleBasicAuthRouting(w, r, sep)
if err != nil {
h.Parent.Option.Logger.LogHTTPRequest(r, "host-http", 401, requestHostname, "")
return true
}
} else if sep.AuthenticationProvider.AuthMethod == AuthMethodAuthelia {
err := h.handleAutheliaAuth(w, r)
if err != nil {
h.Parent.Option.Logger.LogHTTPRequest(r, "host-http", 401, requestHostname, "")
return true
}
} else if sep.AuthenticationProvider.AuthMethod == AuthMethodAuthentik {
err := h.handleAuthentikAuth(w, r)
case AuthMethodForward:
err := h.handleForwardAuth(w, r)
if err != nil {
h.Parent.Option.Logger.LogHTTPRequest(r, "host-http", 401, requestHostname, "")
return true
@@ -106,13 +102,9 @@ func handleBasicAuth(w http.ResponseWriter, r *http.Request, pe *ProxyEndpoint)
return nil
}
/* Authelia */
/* Forward Auth */
// Handle authelia auth routing
func (h *ProxyHandler) handleAutheliaAuth(w http.ResponseWriter, r *http.Request) error {
return h.Parent.Option.AutheliaRouter.HandleAutheliaAuth(w, r)
}
func (h *ProxyHandler) handleAuthentikAuth(w http.ResponseWriter, r *http.Request) error {
return h.Parent.Option.AuthentikRouter.HandleAuthentikAuth(w, r)
// Handle forward auth routing
func (h *ProxyHandler) handleForwardAuth(w http.ResponseWriter, r *http.Request) error {
return h.Parent.Option.ForwardAuthRouter.HandleAuthProviderRouting(w, r)
}

View File

@@ -17,12 +17,13 @@ import (
// GetDefaultAuthenticationProvider return a default authentication provider
func GetDefaultAuthenticationProvider() *AuthenticationProvider {
return &AuthenticationProvider{
AuthMethod: AuthMethodNone,
BasicAuthCredentials: []*BasicAuthCredentials{},
BasicAuthExceptionRules: []*BasicAuthExceptionRule{},
BasicAuthGroupIDs: []string{},
AutheliaURL: "",
UseHTTPS: false,
AuthMethod: AuthMethodNone,
BasicAuthCredentials: []*BasicAuthCredentials{},
BasicAuthExceptionRules: []*BasicAuthExceptionRule{},
BasicAuthGroupIDs: []string{},
ForwardAuthURL: "",
ForwardAuthResponseHeaders: []string{},
ForwardAuthRequestExcludedCookies: []string{},
}
}

View File

@@ -9,13 +9,12 @@ package dynamicproxy
*/
import (
_ "embed"
"imuslab.com/zoraxy/mod/auth/sso/authentik"
"net"
"net/http"
"sync"
"imuslab.com/zoraxy/mod/access"
"imuslab.com/zoraxy/mod/auth/sso/authelia"
"imuslab.com/zoraxy/mod/auth/sso/forward"
"imuslab.com/zoraxy/mod/dynamicproxy/dpcore"
"imuslab.com/zoraxy/mod/dynamicproxy/loadbalance"
"imuslab.com/zoraxy/mod/dynamicproxy/permissionpolicy"
@@ -64,8 +63,7 @@ type RouterOption struct {
PluginManager *plugins.Manager //Plugin manager for handling plugin routing
/* Authentication Providers */
AutheliaRouter *authelia.AutheliaRouter //Authelia router for Authelia authentication
AuthentikRouter *authentik.AuthentikRouter //Authentik router for Authentik authentication
ForwardAuthRouter *forward.AuthRouter
/* Utilities */
Logger *logger.Logger //Logger for reverse proxy requets
@@ -141,11 +139,10 @@ type HeaderRewriteRules struct {
type AuthMethod int
const (
AuthMethodNone AuthMethod = iota //No authentication required
AuthMethodBasic //Basic Auth
AuthMethodAuthelia //Authelia
AuthMethodOauth2 //Oauth2
AuthMethodAuthentik
AuthMethodNone AuthMethod = iota //No authentication required
AuthMethodBasic //Basic Auth
AuthMethodForward //Forward
AuthMethodOauth2 //Oauth2
)
type AuthenticationProvider struct {
@@ -155,9 +152,10 @@ type AuthenticationProvider struct {
BasicAuthExceptionRules []*BasicAuthExceptionRule //Path to exclude in a basic auth enabled proxy target
BasicAuthGroupIDs []string //Group IDs that are allowed to access this endpoint
/* Authelia Settings */
AutheliaURL string //URL of the Authelia server, leave empty to use global settings e.g. authelia.example.com
UseHTTPS bool //Whether to use HTTPS for the Authelia server
/* Forward Auth Settings */
ForwardAuthURL string // Full URL of the Forward Auth endpoint. Example: https://auth.example.com/api/authz/forward-auth
ForwardAuthResponseHeaders []string // List of headers to copy from the forward auth server response to the request.
ForwardAuthRequestExcludedCookies []string // List of cookies to exclude from the request after sending it to the forward auth server.
}
// A proxy endpoint record, a general interface for handling inbound routing

View File

@@ -59,7 +59,7 @@ type AuthProvider int
const (
AuthProviderNone AuthProvider = iota
AuthProviderBasicAuth
AuthProviderAuthelia
AuthProviderForward
AuthProviderOauth2
)