190 lines
5.4 KiB
Go
190 lines
5.4 KiB
Go
package auth
|
|
|
|
import (
|
|
"crypto/rsa"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"slices"
|
|
|
|
"github.com/gookit/goutil/dump"
|
|
"github.com/zeevdiukman/zprox/internal/config"
|
|
"github.com/zeevdiukman/zprox/internal/session"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
func Middleware(routerData *config.Router, routeID string, w http.ResponseWriter, r *http.Request, rp *httputil.ReverseProxy) {
|
|
authConfig := config.Data.AuthMap[routerData.Auth.Provider]
|
|
|
|
// dump.P("routerData.Auth.Provider", routerData.Auth.Provider)
|
|
// dump.P("authConfig.OpenID.EndPoints.RedirectURI", authConfig.OpenID.EndPoints.RedirectURI)
|
|
// dump.P("config.Data.AuthMap[routerData.Auth.Provider]", config.Data.AuthMap[routerData.Auth.Provider].OpenID.EndPoints.RedirectURI)
|
|
if !routerData.IsAuthRouter && !IsLoggedIn(r, authConfig, routerData, routeID) {
|
|
RedirectToLogin(authConfig, w, r)
|
|
|
|
return
|
|
}
|
|
rp.ServeHTTP(w, r)
|
|
|
|
}
|
|
|
|
// func IsLoggedIn(r *http.Request, routerData *config.Router, routeID string) bool {
|
|
// if oauth2Token, ok := session.Manager.Get(r.Context(), "oauth2_token").(*oauth2.Token); ok {
|
|
// if publicKey, ok := session.Manager.Get(r.Context(), "jwks_public_key").(*rsa.PublicKey); ok {
|
|
// if claims, isValid := GetJwtClaims(r, publicKey, oauth2Token); isValid {
|
|
// allowLists := routerData.Auth.JWT.AllowLists
|
|
// for listName, list := range allowLists {
|
|
// if len(list) > 0 {
|
|
// if claim, ok := claims[listName]; ok {
|
|
// if !slices.Contains(list, claim.(string)) {
|
|
// return false
|
|
// } else {
|
|
// dump.P("Hello " + claims["name"].(string))
|
|
// }
|
|
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// if !oauth2Token.Valid() {
|
|
// return false
|
|
// }
|
|
// }
|
|
// dump.P("IsLoggedIn: token is not valid")
|
|
// return false
|
|
|
|
// }
|
|
// dump.P("IsLoggedIn: no token")
|
|
|
|
// return false
|
|
// }
|
|
func IsLoggedIn(r *http.Request, authConfig *config.Auth, routerData *config.Router, routeID string) bool {
|
|
var oauth2Token *oauth2.Token
|
|
var publicKey *rsa.PublicKey
|
|
var oauth2TokenOK bool
|
|
var publicKeyOK bool
|
|
if oauth2Token, oauth2TokenOK = session.Manager.Get(r.Context(), "oauth2_token").(*oauth2.Token); !oauth2TokenOK {
|
|
// dump.P("no oauth2Token")
|
|
|
|
return false
|
|
}
|
|
if publicKey, publicKeyOK = session.Manager.Get(r.Context(), "jwks_public_key").(*rsa.PublicKey); !publicKeyOK {
|
|
dump.P("publicKey not valid")
|
|
|
|
return false
|
|
}
|
|
if !oauth2Token.Valid() {
|
|
dump.P("oauth2Token not valid")
|
|
return false
|
|
}
|
|
|
|
claims, err := GetJwtClaims(r, publicKey, oauth2Token)
|
|
if err != nil {
|
|
dump.P(err.Error())
|
|
return false
|
|
}
|
|
if err := claims.Valid(); err != nil {
|
|
dump.P(err.Error())
|
|
|
|
return false
|
|
}
|
|
|
|
// dump.P(claims)
|
|
// conf := &oauth2.Config{
|
|
// ClientID: authConfig.OpenID.ClientID,
|
|
// ClientSecret: authConfig.OpenID.ClientSecret,
|
|
// RedirectURL: authConfig.OpenID.RedirectURI,
|
|
// Scopes: []string{"openid", "email", "profile"},
|
|
// Endpoint: oauth2.Endpoint{
|
|
// AuthURL: authConfig.OpenID.AuthURL,
|
|
// TokenURL: authConfig.OpenID.TokenURL,
|
|
// },
|
|
// }
|
|
// u,_ := url.Parse(authConfig.OpenID.UserURL)
|
|
// u.
|
|
// client := conf.Client(r.Context(),oauth2Token)
|
|
// client.PostForm(authConfig.OpenID.UserURL,url.Values{})
|
|
// tokenSource := conf.TokenSource(r.Context(), oauth2Token)
|
|
// tokenSource.Token()
|
|
// if !oauth2Token.Valid() {
|
|
|
|
// timeNow := time.Now()
|
|
// if !oauth2Token.Expiry.Before(timeNow) {
|
|
// return false
|
|
// }
|
|
// openID := config.Data.AuthMap[routerData.Auth.Provider].OpenID
|
|
// conf := &oauth2.Config{
|
|
// ClientID: openID.ClientID,
|
|
// ClientSecret: openID.ClientSecret,
|
|
// RedirectURL: openID.RedirectURI,
|
|
// Scopes: []string{"openid", "email", "profile"},
|
|
// Endpoint: endPoint,
|
|
// }
|
|
|
|
// oauth2Token, err := conf.Exchange(r.Context(), code)
|
|
// if err != nil {
|
|
// return false
|
|
// log.Println(err.Error())
|
|
// }
|
|
// return false
|
|
// }
|
|
|
|
for listName, list := range routerData.Auth.JWT.AllowLists {
|
|
if len(list) > 0 {
|
|
if claim, ok := claims[listName]; ok {
|
|
if !slices.Contains(list, claim.(string)) {
|
|
return false
|
|
} else {
|
|
dump.P("Hello " + claims["name"].(string))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// func getAccessToken(refreshToken string) (TokenResponse, error) {
|
|
// keycloakURL := os.Getenv("KEYCLOAK_URL")
|
|
// realm := os.Getenv("KEYCLOAK_REALM")
|
|
// clientID := os.Getenv("KEYCLOAK_CLIENT_ID")
|
|
// clientSecret := os.Getenv("KEYCLOAK_CLIENT_SECRET")
|
|
|
|
// tokenURL := fmt.Sprintf("%s/auth/realms/%s/protocol/openid-connect/token", keycloakURL, realm)
|
|
|
|
// data := url.Values{}
|
|
// data.Set("grant_type", "refresh_token")
|
|
// data.Set("client_id", clientID)
|
|
// data.Set("client_secret", clientSecret)
|
|
// data.Set("refresh_token", refreshToken)
|
|
|
|
// req, err := http.NewRequest("POST", tokenURL, bytes.NewBufferString(data.Encode()))
|
|
// if err != nil {
|
|
// return TokenResponse{}, err
|
|
// }
|
|
|
|
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
// client := &http.Client{}
|
|
// resp, err := client.Do(req)
|
|
// if err != nil {
|
|
// return TokenResponse{}, err
|
|
// }
|
|
// defer resp.Body.Close()
|
|
|
|
// body, err := io.ReadAll(resp.Body)
|
|
// if err != nil {
|
|
// return TokenResponse{}, err
|
|
// }
|
|
|
|
// if resp.StatusCode != http.StatusOK {
|
|
// return TokenResponse{}, fmt.Errorf("Keycloak returned status: %d, body: %s", resp.StatusCode, string(body))
|
|
// }
|
|
|
|
// var tokenResponse TokenResponse
|
|
// err = json.Unmarshal(body, &tokenResponse)
|
|
// if err != nil {
|
|
// return TokenResponse{}, err
|
|
// }
|
|
|
|
// return tokenResponse, nil
|
|
// }
|