diff options
Diffstat (limited to 'weed/s3api/auth_credentials.go')
| -rw-r--r-- | weed/s3api/auth_credentials.go | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/weed/s3api/auth_credentials.go b/weed/s3api/auth_credentials.go index 148839d3e..b5824f2d1 100644 --- a/weed/s3api/auth_credentials.go +++ b/weed/s3api/auth_credentials.go @@ -40,6 +40,7 @@ type IdentityAccessManagement struct { identities []*Identity accessKeyIdent map[string]*Identity + nameToIdentity map[string]*Identity // O(1) lookup by identity name accounts map[string]*Account emailAccount map[string]*Account hashes map[string]*sync.Pool @@ -219,6 +220,7 @@ func NewIdentityAccessManagementWithStore(option *S3ApiServerOption, explicitSto if len(iam.identities) == 0 { iam.identities = []*Identity{envIdentity} iam.accessKeyIdent = map[string]*Identity{accessKeyId: envIdentity} + iam.nameToIdentity = map[string]*Identity{envIdentity.Name: envIdentity} iam.isAuthEnabled = true } iam.m.Unlock() @@ -270,6 +272,7 @@ func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3Api var identities []*Identity var identityAnonymous *Identity accessKeyIdent := make(map[string]*Identity) + nameToIdentity := make(map[string]*Identity) accounts := make(map[string]*Account) emailAccount := make(map[string]*Account) foundAccountAdmin := false @@ -348,6 +351,7 @@ func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3Api accessKeyIdent[cred.AccessKey] = t } identities = append(identities, t) + nameToIdentity[t.Name] = t } iam.m.Lock() @@ -357,6 +361,7 @@ func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3Api iam.accounts = accounts iam.emailAccount = emailAccount iam.accessKeyIdent = accessKeyIdent + iam.nameToIdentity = nameToIdentity if !iam.isAuthEnabled { // one-directional, no toggling iam.isAuthEnabled = len(identities) > 0 } @@ -365,7 +370,7 @@ func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3Api // Log configuration summary glog.V(1).Infof("Loaded %d identities, %d accounts, %d access keys. Auth enabled: %v", len(identities), len(accounts), len(accessKeyIdent), iam.isAuthEnabled) - + if glog.V(2) { glog.V(2).Infof("Access key to identity mapping:") for accessKey, identity := range accessKeyIdent { @@ -383,29 +388,42 @@ func (iam *IdentityAccessManagement) isEnabled() bool { func (iam *IdentityAccessManagement) lookupByAccessKey(accessKey string) (identity *Identity, cred *Credential, found bool) { iam.m.RLock() defer iam.m.RUnlock() - - glog.V(3).Infof("Looking up access key: %s (total keys registered: %d)", accessKey, len(iam.accessKeyIdent)) - + + // Helper function to truncate access key for logging to avoid credential exposure + truncate := func(key string) string { + const mask = "***" + if len(key) > 4 { + return key[:4] + mask + } + // For very short keys, never log the full key + return mask + } + + truncatedKey := truncate(accessKey) + + glog.V(3).Infof("Looking up access key: %s (len=%d, total keys registered: %d)", + truncatedKey, len(accessKey), len(iam.accessKeyIdent)) + if ident, ok := iam.accessKeyIdent[accessKey]; ok { for _, credential := range ident.Credentials { if credential.AccessKey == accessKey { - glog.V(2).Infof("Found access key %s for identity %s", accessKey, ident.Name) + glog.V(2).Infof("Found access key %s for identity %s", truncatedKey, ident.Name) return ident, credential, true } } } - - glog.V(1).Infof("Could not find access key %s. Available keys: %d, Auth enabled: %v", - accessKey, len(iam.accessKeyIdent), iam.isAuthEnabled) - + + glog.V(2).Infof("Could not find access key %s (len=%d). Available keys: %d, Auth enabled: %v", + truncatedKey, len(accessKey), len(iam.accessKeyIdent), iam.isAuthEnabled) + // Log all registered access keys at higher verbosity for debugging if glog.V(3) { glog.V(3).Infof("Registered access keys:") for key := range iam.accessKeyIdent { - glog.V(3).Infof(" - %s", key) + glog.V(3).Infof(" - %s (len=%d)", truncate(key), len(key)) } } - + return nil, nil, false } @@ -418,6 +436,13 @@ func (iam *IdentityAccessManagement) lookupAnonymous() (identity *Identity, foun return nil, false } +func (iam *IdentityAccessManagement) lookupByIdentityName(name string) *Identity { + iam.m.RLock() + defer iam.m.RUnlock() + + return iam.nameToIdentity[name] +} + // generatePrincipalArn generates an ARN for a user identity func generatePrincipalArn(identityName string) string { // Handle special cases @@ -463,6 +488,9 @@ func (iam *IdentityAccessManagement) Auth(f http.HandlerFunc, action Action) htt // Store the authenticated identity in request context (secure, cannot be spoofed) if identity != nil && identity.Name != "" { ctx := s3_constants.SetIdentityNameInContext(r.Context(), identity.Name) + // Also store the full identity object for handlers that need it (e.g., ListBuckets) + // This is especially important for JWT users whose identity is not in the identities list + ctx = s3_constants.SetIdentityInContext(ctx, identity) r = r.WithContext(ctx) } f(w, r) @@ -689,14 +717,14 @@ func (iam *IdentityAccessManagement) GetCredentialManager() *credential.Credenti // LoadS3ApiConfigurationFromCredentialManager loads configuration using the credential manager func (iam *IdentityAccessManagement) LoadS3ApiConfigurationFromCredentialManager() error { glog.V(1).Infof("Loading S3 API configuration from credential manager") - + s3ApiConfiguration, err := iam.credentialManager.LoadConfiguration(context.Background()) if err != nil { glog.Errorf("Failed to load configuration from credential manager: %v", err) return fmt.Errorf("failed to load configuration from credential manager: %w", err) } - glog.V(2).Infof("Credential manager returned %d identities and %d accounts", + glog.V(2).Infof("Credential manager returned %d identities and %d accounts", len(s3ApiConfiguration.Identities), len(s3ApiConfiguration.Accounts)) if err := iam.loadS3ApiConfiguration(s3ApiConfiguration); err != nil { |
