add OAuth2.0 callback/authorize V2 for UI (#353)
* support openID2.0 * generate UUID if it's not set * change OAuth2 callback method to API style
This commit is contained in:
parent
228ffcfbc9
commit
5b9a03a261
|
@ -11,6 +11,7 @@ http:
|
|||
sso:
|
||||
enable: false
|
||||
ssoAddr: "http://10.1.2.3:8071"
|
||||
# TODO: redirectURL: "http://10.1.2.3:8072/auth-callback"
|
||||
redirectURL: "http://10.1.2.3:8072/api/rdb/auth/callback"
|
||||
clientId: ""
|
||||
clientSecret: ""
|
||||
|
@ -21,6 +22,7 @@ sso:
|
|||
phone: "phone"
|
||||
im: ""
|
||||
coverAttributes: false
|
||||
stateExpiresIn: 300
|
||||
|
||||
tokens:
|
||||
- rdb-builtin-token
|
||||
|
|
|
@ -33,6 +33,7 @@ type ssoSection struct {
|
|||
ClientId string `yaml:"clientId"`
|
||||
ClientSecret string `yaml:"clientSecret"`
|
||||
ApiKey string `yaml:"apiKey"`
|
||||
StateExpiresIn int `yaml:"stateExpiresIn"`
|
||||
CoverAttributes bool `yaml:"coverAttributes"`
|
||||
Attributes struct {
|
||||
Dispname string `yaml:"dispname"`
|
||||
|
|
|
@ -21,6 +21,9 @@ func Config(r *gin.Engine) {
|
|||
notLogin.GET("/auth/authorize", authAuthorize)
|
||||
notLogin.GET("/auth/callback", authCallback)
|
||||
notLogin.GET("/auth/settings", authSettings)
|
||||
|
||||
notLogin.GET("/auth/v2/authorize", authAuthorizeV2)
|
||||
notLogin.GET("/auth/v2/callback", authCallbackV2)
|
||||
}
|
||||
|
||||
hbs := r.Group("/api/hbs")
|
||||
|
|
|
@ -110,6 +110,28 @@ func authAuthorize(c *gin.Context) {
|
|||
|
||||
}
|
||||
|
||||
type authRedirect struct {
|
||||
Redirect string `json:"redirect"`
|
||||
}
|
||||
|
||||
func authAuthorizeV2(c *gin.Context) {
|
||||
redirect := queryStr(c, "redirect", "/")
|
||||
ret := &authRedirect{Redirect: redirect}
|
||||
|
||||
username := cookieUsername(c)
|
||||
if username != "" { // alread login
|
||||
renderData(c, ret, nil)
|
||||
return
|
||||
}
|
||||
|
||||
if config.Config.SSO.Enable {
|
||||
ret.Redirect = ssoc.Authorize(redirect)
|
||||
} else {
|
||||
ret.Redirect = "/login"
|
||||
}
|
||||
renderData(c, ret, nil)
|
||||
}
|
||||
|
||||
func authCallback(c *gin.Context) {
|
||||
code := queryStr(c, "code", "")
|
||||
state := queryStr(c, "state", "")
|
||||
|
@ -127,6 +149,29 @@ func authCallback(c *gin.Context) {
|
|||
c.Redirect(302, redirect)
|
||||
}
|
||||
|
||||
func authCallbackV2(c *gin.Context) {
|
||||
code := queryStr(c, "code", "")
|
||||
state := queryStr(c, "state", "")
|
||||
redirect := queryStr(c, "redirect", "")
|
||||
|
||||
ret := &authRedirect{Redirect: redirect}
|
||||
if code == "" && redirect != "" {
|
||||
renderData(c, ret, nil)
|
||||
return
|
||||
}
|
||||
|
||||
var user *models.User
|
||||
var err error
|
||||
ret.Redirect, user, err = ssoc.Callback(code, state)
|
||||
if err != nil {
|
||||
renderData(c, ret, err)
|
||||
return
|
||||
}
|
||||
|
||||
writeCookieUser(c, user.UUID)
|
||||
renderData(c, ret, nil)
|
||||
}
|
||||
|
||||
func authSettings(c *gin.Context) {
|
||||
renderData(c, struct {
|
||||
Sso bool `json:"sso"`
|
||||
|
|
|
@ -24,6 +24,7 @@ type ssoClient struct {
|
|||
config oauth2.Config
|
||||
apiKey string
|
||||
cache *cache.LRUExpireCache
|
||||
stateExpiresIn time.Duration
|
||||
ssoAddr string
|
||||
callbackAddr string
|
||||
coverAttributes bool
|
||||
|
@ -73,12 +74,18 @@ func InitSSO() {
|
|||
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
|
||||
}
|
||||
cli.apiKey = cf.ApiKey
|
||||
|
||||
if cf.StateExpiresIn == 0 {
|
||||
cli.stateExpiresIn = time.Second * 60
|
||||
} else {
|
||||
cli.stateExpiresIn = time.Second * time.Duration(cf.StateExpiresIn)
|
||||
}
|
||||
}
|
||||
|
||||
// Authorize return the sso authorize location with state
|
||||
func Authorize(redirect string) string {
|
||||
state := uuid.New().String()
|
||||
cli.cache.Add(state, redirect, time.Second*60)
|
||||
cli.cache.Add(state, redirect, cli.stateExpiresIn)
|
||||
return cli.config.AuthCodeURL(state)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue