fix: oauth login
This commit is contained in:
parent
07552bc0b1
commit
e61dc2f08a
|
@ -4,8 +4,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -27,12 +29,38 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
state := strings.TrimSpace(gc.Query("state"))
|
state := strings.TrimSpace(gc.Query("state"))
|
||||||
codeChallenge := strings.TrimSpace(gc.Query("code_challenge"))
|
codeChallenge := strings.TrimSpace(gc.Query("code_challenge"))
|
||||||
scopeString := strings.TrimSpace(gc.Query("scope"))
|
scopeString := strings.TrimSpace(gc.Query("scope"))
|
||||||
scope := []string{}
|
clientID := strings.TrimSpace(gc.Query("client_id"))
|
||||||
template := "authorize.tmpl"
|
template := "authorize.tmpl"
|
||||||
|
|
||||||
|
if clientID == "" {
|
||||||
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
|
"target_origin": redirectURI,
|
||||||
|
"authorization_response": map[string]interface{}{
|
||||||
|
"type": "authorization_response",
|
||||||
|
"response": map[string]string{
|
||||||
|
"error": "client_id is required",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) {
|
||||||
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
|
"target_origin": redirectURI,
|
||||||
|
"authorization_response": map[string]interface{}{
|
||||||
|
"type": "authorization_response",
|
||||||
|
"response": map[string]string{
|
||||||
|
"error": "invalid_client_id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if redirectURI == "" {
|
if redirectURI == "" {
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -45,7 +73,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
if state == "" {
|
if state == "" {
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -60,8 +88,11 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
responseType = "token"
|
responseType = "token"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var scope []string
|
||||||
if scopeString == "" {
|
if scopeString == "" {
|
||||||
scope = []string{"openid", "profile", "email"}
|
scope = []string{"openid", "profile", "email"}
|
||||||
|
} else {
|
||||||
|
scope = strings.Split(scopeString, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
isResponseTypeCode := responseType == "code"
|
isResponseTypeCode := responseType == "code"
|
||||||
|
@ -69,7 +100,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
if !isResponseTypeCode && !isResponseTypeToken {
|
if !isResponseTypeCode && !isResponseTypeToken {
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -83,7 +114,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
if isResponseTypeCode {
|
if isResponseTypeCode {
|
||||||
if codeChallenge == "" {
|
if codeChallenge == "" {
|
||||||
gc.HTML(http.StatusBadRequest, template, gin.H{
|
gc.HTML(http.StatusBadRequest, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -98,7 +129,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
sessionToken, err := cookie.GetSession(gc)
|
sessionToken, err := cookie.GetSession(gc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -114,7 +145,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
claims, err := token.ValidateBrowserSession(gc, sessionToken)
|
claims, err := token.ValidateBrowserSession(gc, sessionToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -129,7 +160,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
user, err := db.Provider.GetUserByID(userID)
|
user, err := db.Provider.GetUserByID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -150,7 +181,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
newSessionTokenData, newSessionToken, err := token.CreateSessionToken(user, nonce, claims.Roles, scope)
|
newSessionTokenData, newSessionToken, err := token.CreateSessionToken(user, nonce, claims.Roles, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -168,10 +199,13 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
sessionstore.SetState(codeChallenge, code+"@"+newSessionToken)
|
sessionstore.SetState(codeChallenge, code+"@"+newSessionToken)
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": redirectURI,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]string{
|
"authorization_response": map[string]interface{}{
|
||||||
|
"type": "authorization_response",
|
||||||
|
"response": map[string]string{
|
||||||
"code": code,
|
"code": code,
|
||||||
"state": state,
|
"state": state,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -181,7 +215,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
authToken, err := token.CreateAuthToken(gc, user, claims.Roles, scope)
|
authToken, err := token.CreateAuthToken(gc, user, claims.Roles, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
@ -214,14 +248,17 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": redirectURI,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": res,
|
"authorization_response": map[string]interface{}{
|
||||||
|
"type": "authorization_response",
|
||||||
|
"response": res,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// by default return with error
|
// by default return with error
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": nil,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
"type": "authorization_response",
|
"type": "authorization_response",
|
||||||
"response": map[string]string{
|
"response": map[string]string{
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/coreos/go-oidc/v3/oidc"
|
"github.com/coreos/go-oidc/v3/oidc"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -146,10 +147,14 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
// TODO use query param
|
// TODO use query param
|
||||||
scope := []string{"openid", "email", "profile"}
|
scope := []string{"openid", "email", "profile"}
|
||||||
authToken, _ := token.CreateAuthToken(c, user, inputRoles, scope)
|
nonce := uuid.New().String()
|
||||||
|
_, newSessionToken, err := token.CreateSessionToken(user, nonce, inputRoles, scope)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"error": err.Error()})
|
||||||
|
}
|
||||||
|
|
||||||
sessionstore.SetState(authToken.FingerPrint, user.ID)
|
sessionstore.SetState(newSessionToken, nonce+"@"+user.ID)
|
||||||
cookie.SetSession(c, authToken.FingerPrintHash)
|
cookie.SetSession(c, newSessionToken)
|
||||||
go utils.SaveSessionInDB(c, user.ID)
|
go utils.SaveSessionInDB(c, user.ID)
|
||||||
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -26,7 +28,23 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
codeVerifier := strings.TrimSpace(reqBody["code_verifier"])
|
codeVerifier := strings.TrimSpace(reqBody["code_verifier"])
|
||||||
code := strings.TrimSpace(reqBody["code"])
|
code := strings.TrimSpace(reqBody["code"])
|
||||||
redirectURI := strings.TrimSpace(reqBody["redirect_uri"])
|
clientID := strings.TrimSpace(reqBody["client_id"])
|
||||||
|
|
||||||
|
if clientID == "" {
|
||||||
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"error": "client_id_required",
|
||||||
|
"error_description": "The client id is required",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) {
|
||||||
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"error": "invalid_client_id",
|
||||||
|
"error_description": "The client id is invalid",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if codeVerifier == "" {
|
if codeVerifier == "" {
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
@ -44,14 +62,6 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if redirectURI == "" {
|
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
|
||||||
"error": "invalid_redirect_uri",
|
|
||||||
"error_description": "The redirect URI is required",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hash := sha256.New()
|
hash := sha256.New()
|
||||||
hash.Write([]byte(codeVerifier))
|
hash.Write([]byte(codeVerifier))
|
||||||
encryptedCode := strings.ReplaceAll(base64.URLEncoding.EncodeToString(hash.Sum(nil)), "+", "-")
|
encryptedCode := strings.ReplaceAll(base64.URLEncoding.EncodeToString(hash.Sum(nil)), "+", "-")
|
||||||
|
|
|
@ -26,7 +26,7 @@ func InitRouter() *gin.Engine {
|
||||||
router.GET("/authorize", handlers.AuthorizeHandler())
|
router.GET("/authorize", handlers.AuthorizeHandler())
|
||||||
router.GET("/userinfo", handlers.UserInfoHandler())
|
router.GET("/userinfo", handlers.UserInfoHandler())
|
||||||
router.GET("/logout", handlers.LogoutHandler())
|
router.GET("/logout", handlers.LogoutHandler())
|
||||||
router.POST("/token", handlers.TokenHandler())
|
router.POST("/oauth/token", handlers.TokenHandler())
|
||||||
|
|
||||||
router.LoadHTMLGlob("templates/*")
|
router.LoadHTMLGlob("templates/*")
|
||||||
// login page app related routes.
|
// login page app related routes.
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
(function (window, document) {
|
(function (window, document) {
|
||||||
var targetOrigin = {{.target_origin}};
|
var targetOrigin = {{.target_origin}};
|
||||||
var authorizationResponse = {{.authorization_response}};
|
var authorizationResponse = {{.authorization_response}};
|
||||||
var mainWin = window.parent;
|
console.log({targetOrigin})
|
||||||
mainWin.postMessage(authorizationResponse, targetOrigin);
|
window.parent.postMessage(authorizationResponse, targetOrigin);
|
||||||
})(this, this.document);
|
})(this, this.document);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user