make sure to pass groups for all credentials while verifying policies (#14193)

fixes #14180
This commit is contained in:
Harshavardhana 2022-01-26 21:53:36 -08:00 committed by GitHub
parent a66071099c
commit d6dd17a483
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 9 deletions

View File

@ -951,6 +951,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
// explicit permissions for the user. // explicit permissions for the user.
if !globalIAMSys.IsAllowed(iampolicy.Args{ if !globalIAMSys.IsAllowed(iampolicy.Args{
AccountName: cred.AccessKey, AccountName: cred.AccessKey,
Groups: cred.Groups,
Action: iampolicy.PutObjectAction, Action: iampolicy.PutObjectAction,
ConditionValues: getConditionValues(r, "", cred.AccessKey, cred.Claims), ConditionValues: getConditionValues(r, "", cred.AccessKey, cred.Claims),
BucketName: bucket, BucketName: bucket,

View File

@ -132,13 +132,13 @@ func authenticateURL(accessKey, secretKey string) (string, error) {
// Check if the request is authenticated. // Check if the request is authenticated.
// Returns nil if the request is authenticated. errNoAuthToken if token missing. // Returns nil if the request is authenticated. errNoAuthToken if token missing.
// Returns errAuthentication for all other errors. // Returns errAuthentication for all other errors.
func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, bool, error) { func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, []string, bool, error) {
token, err := jwtreq.AuthorizationHeaderExtractor.ExtractToken(req) token, err := jwtreq.AuthorizationHeaderExtractor.ExtractToken(req)
if err != nil { if err != nil {
if err == jwtreq.ErrNoTokenInRequest { if err == jwtreq.ErrNoTokenInRequest {
return nil, false, errNoAuthToken return nil, nil, false, errNoAuthToken
} }
return nil, false, err return nil, nil, false, err
} }
claims := xjwt.NewMapClaims() claims := xjwt.NewMapClaims()
if err := xjwt.ParseWithClaims(token, claims, func(claims *xjwt.MapClaims) ([]byte, error) { if err := xjwt.ParseWithClaims(token, claims, func(claims *xjwt.MapClaims) ([]byte, error) {
@ -151,20 +151,21 @@ func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, bool, error) {
} }
return []byte(cred.SecretKey), nil return []byte(cred.SecretKey), nil
}); err != nil { }); err != nil {
return claims, false, errAuthentication return claims, nil, false, errAuthentication
} }
owner := true owner := true
var groups []string
if globalActiveCred.AccessKey != claims.AccessKey { if globalActiveCred.AccessKey != claims.AccessKey {
// Check if the access key is part of users credentials. // Check if the access key is part of users credentials.
ucred, ok := globalIAMSys.GetUser(req.Context(), claims.AccessKey) ucred, ok := globalIAMSys.GetUser(req.Context(), claims.AccessKey)
if !ok { if !ok {
return nil, false, errInvalidAccessKeyID return nil, nil, false, errInvalidAccessKeyID
} }
// get embedded claims // get embedded claims
eclaims, s3Err := checkClaimsFromToken(req, ucred) eclaims, s3Err := checkClaimsFromToken(req, ucred)
if s3Err != ErrNone { if s3Err != ErrNone {
return nil, false, errAuthentication return nil, nil, false, errAuthentication
} }
for k, v := range eclaims { for k, v := range eclaims {
@ -177,9 +178,11 @@ func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, bool, error) {
} else { } else {
owner = globalActiveCred.AccessKey == ucred.ParentUser owner = globalActiveCred.AccessKey == ucred.ParentUser
} }
groups = ucred.Groups
} }
return claims, owner, nil return claims, groups, owner, nil
} }
// newCachedAuthToken returns a token that is cached up to 15 seconds. // newCachedAuthToken returns a token that is cached up to 15 seconds.

View File

@ -149,7 +149,7 @@ func TestWebRequestAuthenticate(t *testing.T) {
} }
for i, testCase := range testCases { for i, testCase := range testCases {
_, _, gotErr := webRequestAuthenticate(testCase.req) _, _, _, gotErr := webRequestAuthenticate(testCase.req)
if testCase.expectedErr != gotErr { if testCase.expectedErr != gotErr {
t.Errorf("Test %d, expected err %s, got %s", i+1, testCase.expectedErr, gotErr) t.Errorf("Test %d, expected err %s, got %s", i+1, testCase.expectedErr, gotErr)
} }

View File

@ -674,7 +674,7 @@ func metricsHandler() http.Handler {
// AuthMiddleware checks if the bearer token is valid and authorized. // AuthMiddleware checks if the bearer token is valid and authorized.
func AuthMiddleware(h http.Handler) http.Handler { func AuthMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims, owner, authErr := webRequestAuthenticate(r) claims, groups, owner, authErr := webRequestAuthenticate(r)
if authErr != nil || !claims.VerifyIssuer("prometheus", true) { if authErr != nil || !claims.VerifyIssuer("prometheus", true) {
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
return return
@ -682,6 +682,7 @@ func AuthMiddleware(h http.Handler) http.Handler {
// For authenticated users apply IAM policy. // For authenticated users apply IAM policy.
if !globalIAMSys.IsAllowed(iampolicy.Args{ if !globalIAMSys.IsAllowed(iampolicy.Args{
AccountName: claims.AccessKey, AccountName: claims.AccessKey,
Groups: groups,
Action: iampolicy.PrometheusAdminAction, Action: iampolicy.PrometheusAdminAction,
ConditionValues: getConditionValues(r, "", claims.AccessKey, claims.Map()), ConditionValues: getConditionValues(r, "", claims.AccessKey, claims.Map()),
IsOwner: owner, IsOwner: owner,