From eac592da94bad69c944917df8679663030ce2490 Mon Sep 17 00:00:00 2001 From: kekskurse Date: Thu, 26 Sep 2024 11:00:50 +0200 Subject: [PATCH] easyauth --- Readme.md | 5 +++ easyauth.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 7 +++- go.sum | 2 + 4 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 easyauth.go diff --git a/Readme.md b/Readme.md index 890b5bd..ba62f8f 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,11 @@ Small oAuth2 Client to have an easy way to connect to Authentik # Auth +## Easy Auth +Easy Authentification for default go http lib. + +In Process + ## Low Level Lib / AuthClient The Low Level Lib (Auth) is a Client to provied the basic oAuth2 functions without state. diff --git a/easyauth.go b/easyauth.go new file mode 100644 index 0000000..e5d364e --- /dev/null +++ b/easyauth.go @@ -0,0 +1,103 @@ +package kekskurseauth + +import ( + "net/http" + "time" + + "github.com/golang-jwt/jwt/v5" +) + +type EasyAuth struct { + client Auth + jwtSecret []byte +} + +type UserClaims struct { + jwt.RegisteredClaims + User AuthentikUser +} + +func NewEasyAuth(client Auth) (EasyAuth, error) { + e := EasyAuth{} + e.client = client + e.jwtSecret = []byte("hsajedogö") + return e, nil +} + +func (e EasyAuth) GetUser(w http.ResponseWriter, r *http.Request) (AuthentikUser, bool, error) { + if r.Method == http.MethodGet { + SetCookie(w, "url", r.URL.String(), time.Now().Add(1*time.Minute)) + } + cookie, err := r.Cookie("jwt") + if err != nil { + return AuthentikUser{}, false, err + } + + redirectURL, err := e.client.GetAuthorizationURL("") + if err != nil { + return AuthentikUser{}, false, err + } + + if cookie.Value == "" { + http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect) + return AuthentikUser{}, false, nil + } + + parsedAccessToken, _ := jwt.ParseWithClaims(cookie.Value, &UserClaims{}, func(token *jwt.Token) (interface{}, error) { + return e.jwtSecret, nil + }) + + claims := parsedAccessToken.Claims.(*UserClaims) + + return claims.User, true, nil +} + +func (e EasyAuth) AuthHTTPHandler(w http.ResponseWriter, r *http.Request) { + token, err := e.client.GetTokenFromCode(r.URL.Query().Get("code")) + if err != nil { + panic(err) // TODO: Deal with error + } + + user := AuthentikUser{} + err = e.client.GetUserInfo(token.AccessToken, &user) + if err != nil { + panic(err) // TODO: Deal with error + } + + expired := time.Now().Add(5 * time.Minute) + + claims := UserClaims{} + claims.Issuer = "EasyAuth" + claims.Subject = user.Nickname + claims.IssuedAt = jwt.NewNumericDate(time.Now()) + claims.ExpiresAt = jwt.NewNumericDate(expired) + claims.NotBefore = jwt.NewNumericDate(time.Now()) + claims.User = user + + jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS512, claims) + jwtString, err := jwtToken.SignedString(e.jwtSecret) + if err != nil { + panic(err) // TODO: Deal with error + } + + SetCookie(w, "jwt", jwtString, expired) + + _, err = w.Write([]byte("ok")) // TODO: Redirect to right page + if err != nil { + panic(err) // TODO: Deal with error + } +} + +func SetCookie(w http.ResponseWriter, name, value string, expired time.Time) { + cookie := http.Cookie{} + cookie.Name = name + cookie.Value = value + cookie.Expires = expired + cookie.Path = "/" + cookie.MaxAge = int(time.Until(expired).Seconds()) + cookie.Secure = true + cookie.HttpOnly = true + cookie.SameSite = http.SameSiteStrictMode + + http.SetCookie(w, &cookie) +} diff --git a/go.mod b/go.mod index 2a86f7a..3e9a163 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,11 @@ -module git.keks.cloud/kekskurse/kekskurse-auth +module git.keks.cloud/kekskurse/auth go 1.23.1 -require github.com/stretchr/testify v1.9.0 +require ( + github.com/golang-jwt/jwt/v5 v5.2.1 + github.com/stretchr/testify v1.9.0 +) require ( github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index 60ce688..61da7a6 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=