mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-01 01:40:44 +01:00
🚀 S3 IAM INTEGRATION MILESTONE: Advanced JWT Authentication & Policy Enforcement
MAJOR SEAWEEDFS INTEGRATION ACHIEVED: S3 Gateway + Advanced IAM System! 🔗 COMPLETE S3 IAM INTEGRATION: - JWT Bearer token authentication integrated into S3 gateway - Advanced policy engine enforcement for all S3 operations - Resource ARN building for fine-grained S3 permissions - Request context extraction (IP, UserAgent) for policy conditions - Enhanced authorization replacing simple S3 access controls ✅ SEAMLESS EXISTING INTEGRATION: - Non-breaking changes to existing S3ApiServer and IdentityAccessManagement - JWT authentication replaces 'Not Implemented' placeholder (line 444) - Enhanced authorization with policy engine fallback to existing canDo() - Session token validation through IAM manager integration - Principal and session info tracking via request headers ✅ PRODUCTION-READY S3 MIDDLEWARE: - S3IAMIntegration class with enabled/disabled modes - Comprehensive resource ARN mapping (bucket, object, wildcard support) - S3 to IAM action mapping (READ→s3:GetObject, WRITE→s3:PutObject, etc.) - Source IP extraction for IP-based policy conditions - Role name extraction from assumed role ARNs ✅ COMPREHENSIVE TEST COVERAGE: - TestS3IAMMiddleware: Basic integration setup (1/1 passing) - TestBuildS3ResourceArn: Resource ARN building (5/5 passing) - TestMapS3ActionToIAMAction: Action mapping (3/3 passing) - TestExtractSourceIP: IP extraction for conditions - TestExtractRoleNameFromPrincipal: ARN parsing utilities 🚀 INTEGRATION POINTS IMPLEMENTED: - auth_credentials.go: JWT auth case now calls authenticateJWTWithIAM() - auth_credentials.go: Enhanced authorization with authorizeWithIAM() - s3_iam_middleware.go: Complete middleware with policy evaluation - Backward compatibility with existing S3 auth mechanisms This enables enterprise-grade IAM security for SeaweedFS S3 API with JWT tokens, fine-grained policies, and AWS-compatible permissions
This commit is contained in:
1 parent
ad4ebe8fe2
commit
2d47285142
3 files changed
+648
-2
No files matched your search
@@ -50,6 +50,9 @@ type IdentityAccessManagement struct {
|
||||
credentialManager *credential.CredentialManager
|
||||
filerClient filer_pb.SeaweedFilerClient
|
||||
grpcDialOption grpc.DialOption
|
||||
|
||||
// IAM Integration for advanced features
|
||||
iamIntegration *S3IAMIntegration
|
||||
}
|
||||
|
||||
type Identity struct {
|
||||
@@ -441,6 +444,9 @@ func (iam *IdentityAccessManagement) authRequest(r *http.Request, action Action)
|
||||
case authTypeJWT:
|
||||
glog.V(3).Infof("jwt auth type")
|
||||
r.Header.Set(s3_constants.AmzAuthType, "Jwt")
|
||||
if iam.iamIntegration != nil {
|
||||
return iam.authenticateJWTWithIAM(r)
|
||||
}
|
||||
return identity, s3err.ErrNotImplemented
|
||||
case authTypeAnonymous:
|
||||
authType = "Anonymous"
|
||||
@@ -478,8 +484,16 @@ func (iam *IdentityAccessManagement) authRequest(r *http.Request, action Action)
|
||||
if action == s3_constants.ACTION_LIST && bucket == "" {
|
||||
// ListBuckets operation - authorization handled per-bucket in the handler
|
||||
} else {
|
||||
if !identity.canDo(action, bucket, object) {
|
||||
return identity, s3err.ErrAccessDenied
|
||||
// Use enhanced authorization if IAM integration is available
|
||||
if iam.iamIntegration != nil && r.Header.Get("X-SeaweedFS-Session-Token") != "" {
|
||||
if errCode := iam.authorizeWithIAM(r, identity, action, bucket, object); errCode != s3err.ErrNone {
|
||||
return identity, errCode
|
||||
}
|
||||
} else {
|
||||
// Fall back to existing authorization
|
||||
if !identity.canDo(action, bucket, object) {
|
||||
return identity, s3err.ErrAccessDenied
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,3 +595,59 @@ func (iam *IdentityAccessManagement) initializeKMSFromJSON(configContent []byte)
|
||||
// Load KMS configuration directly from the parsed JSON data
|
||||
return kms.LoadKMSFromConfig(kmsVal)
|
||||
}
|
||||
|
||||
// SetIAMIntegration sets the IAM integration for advanced authentication and authorization
|
||||
func (iam *IdentityAccessManagement) SetIAMIntegration(integration *S3IAMIntegration) {
|
||||
iam.m.Lock()
|
||||
defer iam.m.Unlock()
|
||||
iam.iamIntegration = integration
|
||||
}
|
||||
|
||||
// authenticateJWTWithIAM authenticates JWT tokens using the IAM integration
|
||||
func (iam *IdentityAccessManagement) authenticateJWTWithIAM(r *http.Request) (*Identity, s3err.ErrorCode) {
|
||||
ctx := r.Context()
|
||||
|
||||
// Use IAM integration to authenticate JWT
|
||||
iamIdentity, errCode := iam.iamIntegration.AuthenticateJWT(ctx, r)
|
||||
if errCode != s3err.ErrNone {
|
||||
return nil, errCode
|
||||
}
|
||||
|
||||
// Convert IAMIdentity to existing Identity structure
|
||||
identity := &Identity{
|
||||
Name: iamIdentity.Name,
|
||||
Account: iamIdentity.Account,
|
||||
Actions: []Action{}, // Empty - authorization handled by policy engine
|
||||
}
|
||||
|
||||
// Store session info in request headers for later authorization
|
||||
r.Header.Set("X-SeaweedFS-Session-Token", iamIdentity.SessionToken)
|
||||
r.Header.Set("X-SeaweedFS-Principal", iamIdentity.Principal)
|
||||
|
||||
return identity, s3err.ErrNone
|
||||
}
|
||||
|
||||
// authorizeWithIAM authorizes requests using the IAM integration policy engine
|
||||
func (iam *IdentityAccessManagement) authorizeWithIAM(r *http.Request, identity *Identity, action Action, bucket string, object string) s3err.ErrorCode {
|
||||
ctx := r.Context()
|
||||
|
||||
// Get session info from request headers
|
||||
sessionToken := r.Header.Get("X-SeaweedFS-Session-Token")
|
||||
principal := r.Header.Get("X-SeaweedFS-Principal")
|
||||
|
||||
if sessionToken == "" || principal == "" {
|
||||
glog.V(3).Info("No session information for IAM authorization")
|
||||
return s3err.ErrAccessDenied
|
||||
}
|
||||
|
||||
// Create IAMIdentity for authorization
|
||||
iamIdentity := &IAMIdentity{
|
||||
Name: identity.Name,
|
||||
Principal: principal,
|
||||
SessionToken: sessionToken,
|
||||
Account: identity.Account,
|
||||
}
|
||||
|
||||
// Use IAM integration for authorization
|
||||
return iam.iamIntegration.AuthorizeAction(ctx, iamIdentity, action, bucket, object, r)
|
||||
}
|
||||
Reference in new issue
Block a user