authelia.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package authelia
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/http"
  6. "net/url"
  7. "imuslab.com/zoraxy/mod/dynamicproxy"
  8. "imuslab.com/zoraxy/mod/info/logger"
  9. )
  10. type Options struct {
  11. AutheliaURL string //URL of the Authelia server, e.g. authelia.example.com
  12. UseHTTPS bool //Whether to use HTTPS for the Authelia server
  13. Logger logger.Logger
  14. }
  15. type AutheliaHandler struct {
  16. options *Options
  17. }
  18. func NewAutheliaAuthenticator(options *Options) *AutheliaHandler {
  19. return &AutheliaHandler{
  20. options: options,
  21. }
  22. }
  23. // HandleAutheliaAuthRouting is the handler for Authelia authentication, if the error is not nil, the request will be forwarded to the endpoint
  24. // Do not continue processing or write to the response writer if the error is not nil
  25. func (h *AutheliaHandler) HandleAutheliaAuthRouting(w http.ResponseWriter, r *http.Request, pe *dynamicproxy.ProxyEndpoint) error {
  26. err := h.handleAutheliaAuth(w, r)
  27. if err != nil {
  28. return nil
  29. }
  30. return err
  31. }
  32. func (h *AutheliaHandler) handleAutheliaAuth(w http.ResponseWriter, r *http.Request) error {
  33. client := &http.Client{}
  34. protocol := "http"
  35. if h.options.UseHTTPS {
  36. protocol = "https"
  37. }
  38. autheliaBaseURL := protocol + "://" + h.options.AutheliaURL
  39. //Remove tailing slash if any
  40. if autheliaBaseURL[len(autheliaBaseURL)-1] == '/' {
  41. autheliaBaseURL = autheliaBaseURL[:len(autheliaBaseURL)-1]
  42. }
  43. //Make a request to Authelia to verify the request
  44. req, err := http.NewRequest("POST", autheliaBaseURL+"/api/verify", nil)
  45. if err != nil {
  46. h.options.Logger.PrintAndLog("Authelia", "Unable to create request", err)
  47. w.WriteHeader(401)
  48. return errors.New("unauthorized")
  49. }
  50. scheme := "http"
  51. if r.TLS != nil {
  52. scheme = "https"
  53. }
  54. req.Header.Add("X-Original-URL", fmt.Sprintf("%s://%s", scheme, r.Host))
  55. // Copy cookies from the incoming request
  56. for _, cookie := range r.Cookies() {
  57. req.AddCookie(cookie)
  58. }
  59. // Making the verification request
  60. resp, err := client.Do(req)
  61. if err != nil {
  62. h.options.Logger.PrintAndLog("Authelia", "Unable to verify", err)
  63. w.WriteHeader(401)
  64. return errors.New("unauthorized")
  65. }
  66. if resp.StatusCode != 200 {
  67. redirectURL := autheliaBaseURL + "/?rd=" + url.QueryEscape(scheme+"://"+r.Host+r.URL.String()) + "&rm=" + r.Method
  68. http.Redirect(w, r, redirectURL, http.StatusSeeOther)
  69. return errors.New("unauthorized")
  70. }
  71. return nil
  72. }