mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-04 07:07:18 +00:00
fix(s3api): propagate admin permissions to assumed role session when using caller identity fallback
This commit is contained in:
@@ -434,6 +434,11 @@ func (iam *IdentityAccessManagement) validateSTSSessionToken(r *http.Request, se
|
||||
Claims: claims, // Populate Claims for policy variable substitution
|
||||
}
|
||||
|
||||
// Restore admin privileges if the session was created by an admin
|
||||
if isAdmin, ok := claims["is_admin"].(bool); ok && isAdmin {
|
||||
identity.Actions = append(identity.Actions, s3_constants.ACTION_ADMIN)
|
||||
}
|
||||
|
||||
glog.V(2).Infof("Successfully validated STS session token for principal: %s, assumed role user: %s",
|
||||
sessionInfo.Principal, sessionInfo.AssumedRoleUser)
|
||||
return identity, cred, s3err.ErrNone
|
||||
|
||||
+12
-1
@@ -328,8 +328,19 @@ func (h *STSHandlers) handleAssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Prepare custom claims for the session
|
||||
var modifyClaims func(claims *sts.STSSessionClaims)
|
||||
if identity.isAdmin() {
|
||||
modifyClaims = func(claims *sts.STSSessionClaims) {
|
||||
if claims.RequestContext == nil {
|
||||
claims.RequestContext = make(map[string]interface{})
|
||||
}
|
||||
claims.RequestContext["is_admin"] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Generate common STS components
|
||||
stsCreds, assumedUser, err := h.prepareSTSCredentials(roleArn, roleSessionName, durationSeconds, sessionPolicyJSON, nil)
|
||||
stsCreds, assumedUser, err := h.prepareSTSCredentials(roleArn, roleSessionName, durationSeconds, sessionPolicyJSON, modifyClaims)
|
||||
if err != nil {
|
||||
h.writeSTSErrorResponse(w, r, STSErrInternalError, err)
|
||||
return
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/sts"
|
||||
"github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
|
||||
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -55,13 +57,25 @@ func TestAssumeRole_CallerIdentityFallback(t *testing.T) {
|
||||
Name: "alice",
|
||||
Account: &AccountAdmin,
|
||||
PrincipalArn: fmt.Sprintf("arn:aws:iam::%s:user/alice", defaultAccountID),
|
||||
Actions: []Action{s3_constants.ACTION_ADMIN},
|
||||
}
|
||||
|
||||
// 1. Test prepareSTSCredentials with NO RoleArn (simulating the fallback logic having passed PrincipalArn)
|
||||
// expected RoleArn passed to prepareSTSCredentials would be the caller's PrincipalArn
|
||||
fallbackRoleArn := callerIdentity.PrincipalArn
|
||||
|
||||
stsCreds, assumedUser, err := stsHandlers.prepareSTSCredentials(fallbackRoleArn, "test-session", nil, "", nil)
|
||||
// Prepare custom claims for the session (mimicking handleAssumeRole logic)
|
||||
var modifyClaims func(claims *sts.STSSessionClaims)
|
||||
if callerIdentity.isAdmin() {
|
||||
modifyClaims = func(claims *sts.STSSessionClaims) {
|
||||
if claims.RequestContext == nil {
|
||||
claims.RequestContext = make(map[string]interface{})
|
||||
}
|
||||
claims.RequestContext["is_admin"] = true
|
||||
}
|
||||
}
|
||||
|
||||
stsCreds, assumedUser, err := stsHandlers.prepareSTSCredentials(fallbackRoleArn, "test-session", nil, "", modifyClaims)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assertions
|
||||
@@ -75,6 +89,11 @@ func TestAssumeRole_CallerIdentityFallback(t *testing.T) {
|
||||
|
||||
// The RoleArn in session info should match the fallback ARN (user ARN)
|
||||
assert.Equal(t, fallbackRoleArn, sessionInfo.RoleArn)
|
||||
|
||||
// Verify is_admin claim is present
|
||||
isAdmin, ok := sessionInfo.RequestContext["is_admin"].(bool)
|
||||
assert.True(t, ok, "is_admin claim should be present")
|
||||
assert.True(t, isAdmin, "is_admin claim should be true")
|
||||
})
|
||||
|
||||
// Test case 2: Caller is an STS Assumed Role, No RoleArn
|
||||
|
||||
Reference in New Issue
Block a user