Skip to content

Commit

Permalink
upd
Browse files Browse the repository at this point in the history
  • Loading branch information
vslinko committed Apr 10, 2024
1 parent 38b3e85 commit 2332999
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 15 deletions.
3 changes: 3 additions & 0 deletions .traefik.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ import: github.com/vslinko/secret-auth
summary: 'Authorise requests by secret cookie'

testData:
cookieName: "myCookie"
secretKey: "123"
authUrl: "https://auth.example.com/"
returnUrlParam: "return_to"
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ http:
secret-auth:
plugin:
secret-auth:
cookieName: myCookie
secretKey: mySecretKey
cookieName: "myCookie"
secretKey: "123"
authUrl: "https://auth.example.com/"
returnUrlParam: "return_to"
```
61 changes: 50 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,31 @@ import (
"context"
"fmt"
"net/http"
"net/url"
)

type Config struct {
CookieName string `json:"cookieName,omitempty"`
SecretKey string `json:"secretKey,omitempty"`
CookieName string `json:"cookieName,omitempty"`
SecretKey string `json:"secretKey,omitempty"`
AuthUrl string `json:"authUrl,omitempty"`
ReturnUrlParam string `json:"returnUrlParam,omitempty"`
}

func CreateConfig() *Config {
return &Config{
CookieName: "secret",
SecretKey: "",
CookieName: "secret",
SecretKey: "",
AuthUrl: "",
ReturnUrlParam: "return_url",
}
}

type SecretAuthPlugin struct {
next http.Handler
cookieName string
secretKey string
next http.Handler
cookieName string
secretKey string
authUrl string
returnUrlParam string
}

func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
Expand All @@ -30,19 +37,51 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
}

return &SecretAuthPlugin{
next: next,
cookieName: config.CookieName,
secretKey: config.SecretKey,
next: next,
cookieName: config.CookieName,
secretKey: config.SecretKey,
authUrl: config.AuthUrl,
returnUrlParam: config.ReturnUrlParam,
}, nil
}

func (a *SecretAuthPlugin) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
cookie, err := req.Cookie(a.cookieName)

if err != nil || cookie.Value != a.secretKey {
http.Error(rw, "Forbidden", http.StatusForbidden)
if a.authUrl != "" {
// Obtain the complete request URL
requestURL := getFullURL(req)

// Construct the URL for redirection
redirectURL := fmt.Sprintf("%s?%s=%s", a.authUrl, a.returnUrlParam, url.QueryEscape(requestURL))

// Perform the redirection
http.Redirect(rw, req, redirectURL, http.StatusTemporaryRedirect)
} else {
http.Error(rw, "Forbidden", http.StatusForbidden)
}

return
}

a.next.ServeHTTP(rw, req)
}

func getFullURL(req *http.Request) string {
scheme := "http" // Default to HTTP
if req.TLS != nil || req.Header.Get("X-Forwarded-Proto") == "https" {
// This checks if the underlying connection is TLS (indicating HTTPS) or
// if the request was originally received as HTTPS before being forwarded (common in proxies/load balancers)
scheme = "https"
}

fullURL := fmt.Sprintf("%s://%s%s", scheme, req.Host, req.URL.Path)

// If there are query parameters, append them as well
if rawQuery := req.URL.RawQuery; rawQuery != "" {
fullURL += "?" + rawQuery
}

return fullURL
}
9 changes: 7 additions & 2 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,13 @@ func handler(w http.ResponseWriter, r *http.Request) {
MaxAge: 60 * 60 * 24 * 365,
})

// Respond to the client
http.Redirect(w, r, os.Getenv("S_REDIRECT_URL"), http.StatusFound)
// Respond to the client; check for the return_url query param
// Use the return_url for redirection if present, otherwise use the environment variable
redirectURL := os.Getenv("S_REDIRECT_URL") // Default redirect URL from env var
if returnURL := r.URL.Query().Get("return_url"); returnURL != "" {
redirectURL = returnURL // Override with the return_url query param if present
}
http.Redirect(w, r, redirectURL, http.StatusFound)
}

func parseAuth(r *http.Request) (username, password string, ok bool) {
Expand Down

0 comments on commit 2332999

Please sign in to comment.