|
@@ -4,7 +4,6 @@ import (
|
|
|
"context"
|
|
|
_ "embed"
|
|
|
"encoding/json"
|
|
|
- "fmt"
|
|
|
"log"
|
|
|
"net/http"
|
|
|
"net/url"
|
|
@@ -20,6 +19,10 @@ import (
|
|
|
"imuslab.com/zoraxy/mod/utils"
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ SSO_SESSION_NAME = "ZoraxySSO"
|
|
|
+)
|
|
|
+
|
|
|
type OAuth2Server struct {
|
|
|
srv *server.Server //oAuth server instance
|
|
|
config *SSOConfig
|
|
@@ -37,7 +40,7 @@ func NewOAuth2Server(config *SSOConfig, parent *SSOHandler) (*OAuth2Server, erro
|
|
|
manager := manage.NewDefaultManager()
|
|
|
manager.SetAuthorizeCodeTokenCfg(manage.DefaultAuthorizeCodeTokenCfg)
|
|
|
// token store
|
|
|
- manager.MustTokenStorage(store.NewMemoryTokenStore())
|
|
|
+ manager.MustTokenStorage(store.NewFileTokenStore("./conf/sso.db"))
|
|
|
// generate jwt access token
|
|
|
manager.MapAccessGenerate(generates.NewAccessGenerate())
|
|
|
|
|
@@ -48,6 +51,7 @@ func NewOAuth2Server(config *SSOConfig, parent *SSOHandler) (*OAuth2Server, erro
|
|
|
Secret: "verysecurepassword",
|
|
|
Domain: "localhost:9094",
|
|
|
})
|
|
|
+ //TODO: LOAD THIS DYNAMICALLY FROM DATABASE
|
|
|
manager.MapClientStorage(clientStore)
|
|
|
|
|
|
thisServer := OAuth2Server{
|
|
@@ -66,15 +70,16 @@ func NewOAuth2Server(config *SSOConfig, parent *SSOHandler) (*OAuth2Server, erro
|
|
|
srv.SetResponseErrorHandler(func(re *errors.Response) {
|
|
|
log.Println("Response Error:", re.Error.Error())
|
|
|
})
|
|
|
+ srv.SetAccessTokenExpHandler(thisServer.ExpireHandler)
|
|
|
thisServer.srv = srv
|
|
|
return &thisServer, nil
|
|
|
}
|
|
|
|
|
|
// Password handler, validate if the given username and password are correct
|
|
|
func (oas *OAuth2Server) PasswordAuthorizationHandler(ctx context.Context, clientID, username, password string) (userID string, err error) {
|
|
|
- fmt.Println(username, password)
|
|
|
- if username == "alanyeung" && password == "password" {
|
|
|
- userID = "alanyeung"
|
|
|
+ //TODO: LOAD THIS DYNAMICALLY FROM DATABASE
|
|
|
+ if username == "test" && password == "test" {
|
|
|
+ userID = "test"
|
|
|
}
|
|
|
return
|
|
|
}
|
|
@@ -86,7 +91,7 @@ func (oas *OAuth2Server) UserAuthorizeHandler(w http.ResponseWriter, r *http.Req
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- uid, ok := store.Get("ZoraxySSO")
|
|
|
+ uid, ok := store.Get(SSO_SESSION_NAME)
|
|
|
if !ok {
|
|
|
if r.Form == nil {
|
|
|
r.ParseForm()
|
|
@@ -101,11 +106,30 @@ func (oas *OAuth2Server) UserAuthorizeHandler(w http.ResponseWriter, r *http.Req
|
|
|
}
|
|
|
|
|
|
userID = uid.(string)
|
|
|
- store.Delete("ZoraxySSO")
|
|
|
+ store.Delete(SSO_SESSION_NAME)
|
|
|
store.Save()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+// AccessTokenExpHandler, set the SSO session length default value
|
|
|
+func (oas *OAuth2Server) ExpireHandler(w http.ResponseWriter, r *http.Request) (exp time.Duration, err error) {
|
|
|
+ requestHostname := r.Host
|
|
|
+ if requestHostname == "" {
|
|
|
+ //Use default value
|
|
|
+ return time.Hour, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ //Get the Registered App Config from parent
|
|
|
+ appConfig, ok := oas.parent.Apps[requestHostname]
|
|
|
+ if !ok {
|
|
|
+ //Use default value
|
|
|
+ return time.Hour, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ //Use the app's session length
|
|
|
+ return time.Second * time.Duration(appConfig.SessionDuration), nil
|
|
|
+}
|
|
|
+
|
|
|
/* SSO Web Server Toggle Functions */
|
|
|
func (oas *OAuth2Server) RegisterOauthEndpoints(primaryMux *http.ServeMux) {
|
|
|
primaryMux.HandleFunc("/oauth2/login", oas.loginHandler)
|
|
@@ -193,7 +217,7 @@ func (oas *OAuth2Server) loginHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- store.Set("ZoraxySSO", r.Form.Get("username"))
|
|
|
+ store.Set(SSO_SESSION_NAME, r.Form.Get("username"))
|
|
|
store.Save()
|
|
|
|
|
|
w.Header().Set("Location", "/oauth2/auth")
|
|
@@ -211,12 +235,15 @@ func (oas *OAuth2Server) authHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- if _, ok := store.Get("ZoraxySSO"); !ok {
|
|
|
+ if _, ok := store.Get(SSO_SESSION_NAME); !ok {
|
|
|
w.Header().Set("Location", "/oauth2/login")
|
|
|
w.WriteHeader(http.StatusFound)
|
|
|
return
|
|
|
}
|
|
|
+ //User logged in. Check if this user have previously authorized the app
|
|
|
+
|
|
|
+ //TODO: Check if the user have previously authorized the app
|
|
|
|
|
|
- //User logged in. Show authentication confirm page
|
|
|
+ //User have not authorized the app. Show the authorization page
|
|
|
w.Write(authHtml)
|
|
|
}
|