aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api/auth_credentials.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/s3api/auth_credentials.go')
-rw-r--r--weed/s3api/auth_credentials.go54
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 {