mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
Migrate config to KV data format (#8392)
- adding oauth support to MinIO browser (#8400) by @kanagaraj - supports multi-line get/set/del for all config fields - add support for comments, allow toggle - add extensive validation of config before saving - support MinIO browser to support proper claims, using STS tokens - env support for all config parameters, legacy envs are also supported with all documentation now pointing to latest ENVs - preserve accessKey/secretKey from FS mode setups - add history support implements three APIs - ClearHistory - RestoreHistory - ListHistory - add help command support for each config parameters - all the bug fixes after migration to KV, and other bug fixes encountered during testing.
This commit is contained in:
committed by
kannappanr
parent
8836d57e3c
commit
ee4a6a823d
132
cmd/jwt.go
132
cmd/jwt.go
@@ -55,24 +55,30 @@ func authenticateJWTUsers(accessKey, secretKey string, expiry time.Duration) (st
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
expiresAt := UTCNow().Add(expiry)
|
||||
return authenticateJWTUsersWithCredentials(passedCredential, expiresAt)
|
||||
}
|
||||
|
||||
serverCred := globalServerConfig.GetCredential()
|
||||
if serverCred.AccessKey != passedCredential.AccessKey {
|
||||
func authenticateJWTUsersWithCredentials(credentials auth.Credentials, expiresAt time.Time) (string, error) {
|
||||
serverCred := globalActiveCred
|
||||
if serverCred.AccessKey != credentials.AccessKey {
|
||||
var ok bool
|
||||
serverCred, ok = globalIAMSys.GetUser(accessKey)
|
||||
serverCred, ok = globalIAMSys.GetUser(credentials.AccessKey)
|
||||
if !ok {
|
||||
return "", errInvalidAccessKeyID
|
||||
}
|
||||
}
|
||||
|
||||
if !serverCred.Equal(passedCredential) {
|
||||
if !serverCred.Equal(credentials) {
|
||||
return "", errAuthentication
|
||||
}
|
||||
|
||||
jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.StandardClaims{
|
||||
ExpiresAt: UTCNow().Add(expiry).Unix(),
|
||||
Subject: accessKey,
|
||||
})
|
||||
claims := jwtgo.MapClaims{}
|
||||
claims["exp"] = expiresAt.Unix()
|
||||
claims["sub"] = credentials.AccessKey
|
||||
claims["accessKey"] = credentials.AccessKey
|
||||
|
||||
jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, claims)
|
||||
return jwt.SignedString([]byte(serverCred.SecretKey))
|
||||
}
|
||||
|
||||
@@ -82,7 +88,7 @@ func authenticateJWTAdmin(accessKey, secretKey string, expiry time.Duration) (st
|
||||
return "", err
|
||||
}
|
||||
|
||||
serverCred := globalServerConfig.GetCredential()
|
||||
serverCred := globalActiveCred
|
||||
|
||||
if serverCred.AccessKey != passedCredential.AccessKey {
|
||||
return "", errInvalidAccessKeyID
|
||||
@@ -92,10 +98,12 @@ func authenticateJWTAdmin(accessKey, secretKey string, expiry time.Duration) (st
|
||||
return "", errAuthentication
|
||||
}
|
||||
|
||||
jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.StandardClaims{
|
||||
ExpiresAt: UTCNow().Add(expiry).Unix(),
|
||||
Subject: accessKey,
|
||||
})
|
||||
claims := jwtgo.MapClaims{}
|
||||
claims["exp"] = UTCNow().Add(expiry).Unix()
|
||||
claims["sub"] = passedCredential.AccessKey
|
||||
claims["accessKey"] = passedCredential.AccessKey
|
||||
|
||||
jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, claims)
|
||||
return jwt.SignedString([]byte(serverCred.SecretKey))
|
||||
}
|
||||
|
||||
@@ -121,18 +129,29 @@ func webTokenCallback(jwtToken *jwtgo.Token) (interface{}, error) {
|
||||
return nil, errAuthentication
|
||||
}
|
||||
|
||||
if claims, ok := jwtToken.Claims.(*jwtgo.StandardClaims); ok {
|
||||
if claims.Subject == globalServerConfig.GetCredential().AccessKey {
|
||||
return []byte(globalServerConfig.GetCredential().SecretKey), nil
|
||||
if claimsPtr, ok := jwtToken.Claims.(*jwtgo.MapClaims); ok {
|
||||
claims := *claimsPtr
|
||||
accessKey, ok := claims["accessKey"].(string)
|
||||
if !ok {
|
||||
accessKey, ok = claims["sub"].(string)
|
||||
if !ok {
|
||||
return nil, errInvalidAccessKeyID
|
||||
}
|
||||
}
|
||||
if accessKey == globalActiveCred.AccessKey {
|
||||
return []byte(globalActiveCred.SecretKey), nil
|
||||
}
|
||||
if globalIAMSys == nil {
|
||||
return nil, errInvalidAccessKeyID
|
||||
}
|
||||
cred, ok := globalIAMSys.GetUser(claims.Subject)
|
||||
if !ok {
|
||||
return nil, errInvalidAccessKeyID
|
||||
if _, ok = claims["aud"].(string); !ok {
|
||||
cred, ok := globalIAMSys.GetUser(accessKey)
|
||||
if !ok {
|
||||
return nil, errInvalidAccessKeyID
|
||||
}
|
||||
return []byte(cred.SecretKey), nil
|
||||
}
|
||||
return []byte(cred.SecretKey), nil
|
||||
return []byte(globalActiveCred.SecretKey), nil
|
||||
}
|
||||
|
||||
return nil, errAuthentication
|
||||
@@ -141,6 +160,10 @@ func webTokenCallback(jwtToken *jwtgo.Token) (interface{}, error) {
|
||||
func parseJWTWithClaims(tokenString string, claims jwtgo.Claims) (*jwtgo.Token, error) {
|
||||
p := &jwtgo.Parser{
|
||||
SkipClaimsValidation: true,
|
||||
ValidMethods: []string{
|
||||
jwtgo.SigningMethodHS256.Alg(),
|
||||
jwtgo.SigningMethodHS512.Alg(),
|
||||
},
|
||||
}
|
||||
jwtToken, err := p.ParseWithClaims(tokenString, claims, webTokenCallback)
|
||||
if err != nil {
|
||||
@@ -161,62 +184,77 @@ func isAuthTokenValid(token string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func webTokenAuthenticate(token string) (standardClaims, bool, error) {
|
||||
var claims = jwtgo.StandardClaims{}
|
||||
func webTokenAuthenticate(token string) (mapClaims, bool, error) {
|
||||
var claims = jwtgo.MapClaims{}
|
||||
if token == "" {
|
||||
return standardClaims{claims}, false, errNoAuthToken
|
||||
return mapClaims{claims}, false, errNoAuthToken
|
||||
}
|
||||
|
||||
jwtToken, err := parseJWTWithClaims(token, &claims)
|
||||
if err != nil {
|
||||
return standardClaims{claims}, false, err
|
||||
return mapClaims{claims}, false, err
|
||||
}
|
||||
if !jwtToken.Valid {
|
||||
return standardClaims{claims}, false, errAuthentication
|
||||
return mapClaims{claims}, false, errAuthentication
|
||||
}
|
||||
owner := claims.Subject == globalServerConfig.GetCredential().AccessKey
|
||||
return standardClaims{claims}, owner, nil
|
||||
accessKey, ok := claims["accessKey"].(string)
|
||||
if !ok {
|
||||
accessKey, ok = claims["sub"].(string)
|
||||
if !ok {
|
||||
return mapClaims{claims}, false, errAuthentication
|
||||
}
|
||||
}
|
||||
owner := accessKey == globalActiveCred.AccessKey
|
||||
return mapClaims{claims}, owner, nil
|
||||
}
|
||||
|
||||
// jwt standardClaims
|
||||
type standardClaims struct {
|
||||
jwtgo.StandardClaims
|
||||
type mapClaims struct {
|
||||
jwtgo.MapClaims
|
||||
}
|
||||
|
||||
func (s standardClaims) Map() map[string]interface{} {
|
||||
m := make(map[string]interface{})
|
||||
m["sub"] = s.Subject
|
||||
m["iss"] = s.Issuer
|
||||
m["aud"] = s.Audience
|
||||
m["jti"] = s.Id
|
||||
return m
|
||||
func (m mapClaims) Map() map[string]interface{} {
|
||||
return m.MapClaims
|
||||
}
|
||||
|
||||
func (m mapClaims) AccessKey() string {
|
||||
claimSub, ok := m.MapClaims["accessKey"].(string)
|
||||
if !ok {
|
||||
claimSub, _ = m.MapClaims["sub"].(string)
|
||||
}
|
||||
return claimSub
|
||||
}
|
||||
|
||||
// Check if the request is authenticated.
|
||||
// Returns nil if the request is authenticated. errNoAuthToken if token missing.
|
||||
// Returns errAuthentication for all other errors.
|
||||
func webRequestAuthenticate(req *http.Request) (standardClaims, bool, error) {
|
||||
var claims = jwtgo.StandardClaims{}
|
||||
func webRequestAuthenticate(req *http.Request) (mapClaims, bool, error) {
|
||||
var claims = jwtgo.MapClaims{}
|
||||
tokStr, err := jwtreq.AuthorizationHeaderExtractor.ExtractToken(req)
|
||||
if err != nil {
|
||||
if err == jwtreq.ErrNoTokenInRequest {
|
||||
return standardClaims{claims}, false, errNoAuthToken
|
||||
return mapClaims{claims}, false, errNoAuthToken
|
||||
}
|
||||
return standardClaims{claims}, false, err
|
||||
return mapClaims{claims}, false, err
|
||||
}
|
||||
jwtToken, err := parseJWTWithClaims(tokStr, &claims)
|
||||
if err != nil {
|
||||
return standardClaims{claims}, false, err
|
||||
return mapClaims{claims}, false, err
|
||||
}
|
||||
if !jwtToken.Valid {
|
||||
return standardClaims{claims}, false, errAuthentication
|
||||
return mapClaims{claims}, false, errAuthentication
|
||||
}
|
||||
owner := claims.Subject == globalServerConfig.GetCredential().AccessKey
|
||||
return standardClaims{claims}, owner, nil
|
||||
accessKey, ok := claims["accessKey"].(string)
|
||||
if !ok {
|
||||
accessKey, ok = claims["sub"].(string)
|
||||
if !ok {
|
||||
return mapClaims{claims}, false, errAuthentication
|
||||
}
|
||||
}
|
||||
owner := accessKey == globalActiveCred.AccessKey
|
||||
return mapClaims{claims}, owner, nil
|
||||
}
|
||||
|
||||
func newAuthToken() string {
|
||||
cred := globalServerConfig.GetCredential()
|
||||
cred := globalActiveCred
|
||||
token, err := authenticateNode(cred.AccessKey, cred.SecretKey)
|
||||
logger.CriticalIf(context.Background(), err)
|
||||
return token
|
||||
|
||||
Reference in New Issue
Block a user