Utilizzo AWS Lambda per integrare il proprio provider di identità - AWS Transfer Family

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Utilizzo AWS Lambda per integrare il proprio provider di identità

Crea una AWS Lambda funzione che si connetta al tuo provider di identità personalizzato. Puoi utilizzare qualsiasi provider di identità personalizzato, come Okta, Secrets Manager OneLogin, o un data store personalizzato che includa la logica di autorizzazione e autenticazione.

Nota

Prima di creare un server Transfer Family che utilizza Lambda come provider di identità, è necessario creare la funzione. Per un esempio di funzione Lambda, consulta Esempi di funzioni Lambda. In alternativa, puoi distribuire uno CloudFormation stack che utilizza uno dei. Modelli di funzioni Lambda Inoltre, assicurati che la tua funzione Lambda utilizzi una politica basata sulle risorse che si affidi a Transfer Family. Per un esempio di policy, consulta Policy Lambda basata sulle risorse.

  1. Apri la AWS Transfer Family console.

  2. Scegli Crea server per aprire la pagina Crea server. Per Scegli un provider di identità, scegli Custom Identity Provider, come mostrato nella schermata seguente.

    La sezione Scegli una console con provider di identità con Provider di identità personalizzato selezionato. È inoltre selezionato il valore predefinito, ovvero che gli utenti possono autenticarsi utilizzando la password o la chiave.
    Nota

    La scelta dei metodi di autenticazione è disponibile solo se abiliti SFTP come uno dei protocolli per il tuo server Transfer Family.

  3. Assicurati che il valore predefinito, Usa AWS Lambda per connettere il tuo provider di identità, sia selezionato.

  4. Per AWS Lambda la funzione, scegli il nome della tua funzione Lambda.

  5. Compila le caselle rimanenti, quindi scegli Crea server. Per i dettagli sui passaggi rimanenti per la creazione di un server, consultaConfigurazione di un endpoint server SFTP, FTPS o FTP.

Policy Lambda basata sulle risorse

È necessario disporre di una policy che faccia riferimento al server Transfer Family e agli ARN Lambda. Ad esempio, puoi utilizzare la seguente politica con la funzione Lambda che si connette al tuo provider di identità. La policy viene salvata in formato JSON come stringa.

"Policy": "{ "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "AllowTransferInvocation", "Effect": "Allow", "Principal": { "Service": "transfer.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:transfer:region:account-id:function:my-lambda-auth-function", "Condition": { "ArnLike": { "AWS:SourceArn": "arn:aws:transfer:region:account-id:server/server-id" } } } ] }"
Nota

Nella politica di esempio precedente, sostituisci ogni segnaposto di input dell'utente con le tue informazioni.

Struttura del messaggio di evento

La struttura dei messaggi di evento dal server SFTP inviati alla funzione di autorizzazione Lambda per un IDP personalizzato è la seguente.

{ "username": "value", "password": "value", "protocol": "SFTP", "serverId": "s-abcd123456", "sourceIp": "192.168.0.100" }

Dove username e password sono i valori per le credenziali di accesso inviate al server.

Ad esempio, si immette il seguente comando per connettersi:

sftp bobusa@server_hostname

Ti viene quindi richiesto di inserire la password:

Enter password: mysecretpassword

Puoi verificarlo dalla tua funzione Lambda stampando l'evento passato dall'interno della funzione Lambda. Dovrebbe essere simile al seguente blocco di testo.

{ "username": "bobusa", "password": "mysecretpassword", "protocol": "SFTP", "serverId": "s-abcd123456", "sourceIp": "192.168.0.100" }

La struttura degli eventi è simile per FTP e FTPS: l'unica differenza è che i valori vengono utilizzati per il protocol parametro, anziché SFTP.

Funzioni Lambda per l'autenticazione

Per implementare diverse strategie di autenticazione, modifica la funzione Lambda. Per aiutarti a soddisfare le esigenze della tua applicazione, puoi implementare uno CloudFormation stack. Per ulteriori informazioni su Lambda, consulta la AWS Lambda Developer Guide o Building Lambda functions with Node.js.

Modelli di funzioni Lambda

È possibile distribuire uno AWS CloudFormation stack che utilizza una funzione Lambda per l'autenticazione. Forniamo diversi modelli che autenticano e autorizzano gli utenti utilizzando le credenziali di accesso. Puoi modificare questi modelli o AWS Lambda codici per personalizzare ulteriormente l'accesso degli utenti.

Nota

È possibile creare un AWS Transfer Family server compatibile con FIPS AWS CloudFormation specificando una politica di sicurezza compatibile con FIPS nel modello. Le politiche di sicurezza disponibili sono descritte in Politiche di sicurezza per AWS Transfer Family i server

Per creare uno AWS CloudFormation stack da utilizzare per l'autenticazione
  1. Apri la AWS CloudFormation console all'indirizzo https://console.aws.amazon.com/cloudformation.

  2. Segui le istruzioni per distribuire uno AWS CloudFormation stack da un modello esistente in Selezione di un modello di stack nella Guida per l'AWS CloudFormation utente.

  3. Utilizza uno dei seguenti modelli per creare una funzione Lambda da utilizzare per l'autenticazione in Transfer Family.

    • Modello di pila classico (Amazon Cognito)

      Un modello di base per la creazione di un AWS Lambda file da utilizzare come provider di identità personalizzato in. AWS Transfer Family Si autentica con Amazon Cognito per l'autenticazione basata su password e le chiavi pubbliche vengono restituite da un bucket Amazon S3 se viene utilizzata l'autenticazione basata su chiave pubblica. Dopo la distribuzione, puoi modificare il codice della funzione Lambda per fare qualcosa di diverso.

    • AWS Secrets Manager modello di pila

      Un modello di base che si utilizza AWS Lambda con un AWS Transfer Family server per integrare Secrets Manager come provider di identità. Si autentica in base a una voce AWS Secrets Manager del formato. aws/transfer/server-id/username Inoltre, il segreto deve contenere le coppie chiave-valore per tutte le proprietà utente restituite a Transfer Family. Dopo la distribuzione, puoi modificare il codice della funzione Lambda per fare qualcosa di diverso.

    • Modello stack Okta: un modello di base che utilizza AWS Lambda un AWS Transfer Family server per integrare Okta come provider di identità personalizzato.

    • Modello di stack Okta-MFA: un modello di base che viene utilizzato AWS Lambda con un AWS Transfer Family server per integrare Okta, con autenticazione, come provider di identità personalizzato. MultiFactor

    • Modello di Azure Active Directory: i dettagli per questo stack sono descritti nel post del blog Authenticating to with Azure Active Directory and. AWS Transfer FamilyAWS Lambda

    Dopo aver distribuito lo stack, puoi visualizzarne i dettagli nella scheda Output della console. CloudFormation

    L'implementazione di uno di questi stack è il modo più semplice per integrare un provider di identità personalizzato nel flusso di lavoro Transfer Family.

Valori Lambda validi

La tabella seguente descrive i dettagli dei valori che Transfer Family accetta per le funzioni Lambda utilizzate per i provider di identità personalizzati.

Valore Descrizione Richiesto

Role

Speciifica l'Amazon Resource Name (ARN) del ruolo IAM che controlla l'accesso degli utenti al bucket Amazon S3 o al file system Amazon EFS. Le policy associate a questo ruolo determinano il livello di accesso che desideri fornire ai tuoi utenti durante il trasferimento di file da e verso il tuo file system Amazon S3 o Amazon EFS. Il ruolo IAM deve contenere anche una relazione di trust che consente al server di accedere alle proprie risorse durante la manutenzione delle richieste di trasferimento degli utenti.

Per i dettagli su come stabilire una relazione di fiducia, consulta. Per stabilire una relazione di trust

Richiesto

PosixProfile

L'identità POSIX completa, inclusi ID utente (Uid), ID di gruppo (Gid) ed eventuali ID di gruppo secondari (SecondaryGids), che controlla l'accesso degli utenti ai file system Amazon EFS. Le autorizzazioni POSIX impostate su file e directory nel file system determinano il livello di accesso che gli utenti ottengono durante il trasferimento dei file da e verso i file system Amazon EFS.

Necessario per lo storage di backup di Amazon EFS

PublicKeys

Un elenco di valori di chiave pubblica SSH validi per questo utente. Un elenco vuoto implica che non si tratta di un accesso valido. Non deve essere restituito durante l'autenticazione della password.

Facoltativo

Policy

Una politica di sessione per il tuo utente in modo da poter utilizzare lo stesso ruolo IAM su più utenti. Questa policy definisce gli ambiti di accesso degli utenti alle porzioni dei loro bucket di Amazon S3.

Facoltativo

HomeDirectoryType

Il tipo di directory (cartella) di destinazione in cui deve trovarsi la directory home degli utenti quando accedono al server.

  • Se lo imposti suPATH, l'utente vede il bucket Amazon S3 assoluto o i percorsi Amazon EFS così come sono nei client del protocollo di trasferimento file.

  • Se lo imposti suLOGICAL, devi fornire mappature nel HomeDirectoryDetails parametro per rendere i percorsi Amazon S3 o Amazon EFS visibili ai tuoi utenti.

Facoltativo

HomeDirectoryDetails

Mappature di directory logiche che specificano quali percorsi e chiavi di Amazon S3 o Amazon EFS devono essere visibili all'utente e in che modo desideri renderli visibili. È necessario specificare la Target coppia Entry and, dove Entry mostra come il percorso viene reso visibile ed Target è il percorso effettivo di Amazon S3 o Amazon EFS.

Obbligatorio se HomeDirectoryType ha un valore di LOGICAL

HomeDirectory

La directory di destinazione di un utente quando accede al server utilizzando il client.

Facoltativo

Nota

HomeDirectoryDetailsè una rappresentazione in formato stringa di una mappa JSON. Ciò è in contrasto conPosixProfile, che è un vero oggetto della mappa JSON e PublicKeys che è un array di stringhe JSON. Vedi gli esempi di codice per i dettagli specifici della lingua.

Esempi di funzioni Lambda

Questa sezione presenta alcuni esempi di funzioni Lambda, sia in NodeJS che in Python.

Nota

In questi esempi, i dettagli relativi all'utente, al ruolo, al profilo POSIX, alla password e alla home directory sono tutti esempi e devono essere sostituiti con i valori effettivi.

Logical home directory, NodeJS

La seguente funzione di esempio NodeJS fornisce i dettagli per un utente che dispone di una home directory logica.

// GetUserConfig Lambda exports.handler = (event, context, callback) => { console.log("Username:", event.username, "ServerId: ", event.serverId); var response; // Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. if (event.serverId !== "" && event.username == 'example-user') { var homeDirectoryDetails = [ { Entry: "/", Target: "/fs-faa1a123" } ]; response = { Role: 'arn:aws:iam::123456789012:role/transfer-access-role', // The user is authenticated if and only if the Role field is not blank PosixProfile: {"Gid": 65534, "Uid": 65534}, // Required for EFS access, but not needed for S3 HomeDirectoryDetails: JSON.stringify(homeDirectoryDetails), HomeDirectoryType: "LOGICAL", }; // Check if password is provided if (!event.password) { // If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ]; // Check if password is correct } else if (event.password !== 'Password1234') { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } } else { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } callback(null, response); };
Path-based home directory, NodeJS

La seguente funzione di esempio NodeJS fornisce i dettagli per un utente che dispone di una home directory basata su percorsi.

// GetUserConfig Lambda exports.handler = (event, context, callback) => { console.log("Username:", event.username, "ServerId: ", event.serverId); var response; // Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. // There is also event.protocol (one of "FTP", "FTPS", "SFTP") and event.sourceIp (e.g., "127.0.0.1") to further restrict logins. if (event.serverId !== "" && event.username == 'example-user') { response = { Role: 'arn:aws:iam::123456789012:role/transfer-access-role', // The user is authenticated if and only if the Role field is not blank Policy: '', // Optional, JSON stringified blob to further restrict this user's permissions HomeDirectory: '/fs-faa1a123' // Not required, defaults to '/' }; // Check if password is provided if (!event.password) { // If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ]; // Check if password is correct } else if (event.password !== 'Password1234') { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } } else { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } callback(null, response); };
Logical home directory, Python

La seguente funzione di esempio in Python fornisce i dettagli per un utente che ha una home directory logica.

# GetUserConfig Python Lambda with LOGICAL HomeDirectoryDetails import json def lambda_handler(event, context): print("Username: {}, ServerId: {}".format(event['username'], event['serverId'])) response = {} # Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. if event['serverId'] != '' and event['username'] == 'example-user': homeDirectoryDetails = [ { 'Entry': '/', 'Target': '/fs-faa1a123' } ] response = { 'Role': 'arn:aws:iam::123456789012:role/transfer-access-role', # The user will be authenticated if and only if the Role field is not blank 'PosixProfile': {"Gid": 65534, "Uid": 65534}, # Required for EFS access, but not needed for S3 'HomeDirectoryDetails': json.dumps(homeDirectoryDetails), 'HomeDirectoryType': "LOGICAL" } # Check if password is provided if event.get('password', '') == '': # If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ] # Check if password is correct elif event['password'] != 'Password1234': # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} else: # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} return response
Path-based home directory, Python

La seguente funzione di esempio in Python fornisce i dettagli per un utente che dispone di una home directory basata su percorsi.

# GetUserConfig Python Lambda with PATH HomeDirectory def lambda_handler(event, context): print("Username: {}, ServerId: {}".format(event['username'], event['serverId'])) response = {} # Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. # There is also event.protocol (one of "FTP", "FTPS", "SFTP") and event.sourceIp (e.g., "127.0.0.1") to further restrict logins. if event['serverId'] != '' and event['username'] == 'example-user': response = { 'Role': 'arn:aws:iam::123456789012:role/transfer-access-role', # The user will be authenticated if and only if the Role field is not blank 'Policy': '', # Optional, JSON stringified blob to further restrict this user's permissions 'HomeDirectory': '/fs-fs-faa1a123', 'HomeDirectoryType': "PATH" # Not strictly required, defaults to PATH } # Check if password is provided if event.get('password', '') == '': # If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ] # Check if password is correct elif event['password'] != 'Password1234': # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} else: # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} return response

Verifica della configurazione

Dopo aver creato il tuo provider di identità personalizzato, dovresti testare la configurazione.

Console
Per testare la configurazione utilizzando la AWS Transfer Family console
  1. Apri la AWS Transfer Family console.

  2. Nella pagina Server, scegli il tuo nuovo server, scegli Azioni, quindi scegli Test.

  3. Inserisci il testo per nome utente e password che hai impostato quando hai distribuito lo AWS CloudFormation stack. Se hai mantenuto le opzioni predefinite, il nome utente è myuser e la password è. MySuperSecretPassword

  4. Scegli il protocollo Server e inserisci l'indirizzo IP per l'IP di origine, se lo hai impostato quando hai distribuito lo AWS CloudFormation stack.

CLI
Per testare la configurazione utilizzando la AWS CLI
  1. Esegui il comando test-identity-provider. Sostituisci ciascuno user input placeholder con le tue informazioni, come descritto nei passaggi successivi.

    aws transfer test-identity-provider --server-id s-1234abcd5678efgh --user-name myuser --user-password MySuperSecretPassword --server-protocol FTP --source-ip 127.0.0.1
  2. Inserisci l'ID del server.

  3. Inserisci il nome utente e la password che hai impostato quando hai distribuito lo AWS CloudFormation stack. Se hai mantenuto le opzioni predefinite, il nome utente è myuser e la password è. MySuperSecretPassword

  4. Inserisci il protocollo del server e l'indirizzo IP di origine, se li hai impostati quando hai distribuito lo AWS CloudFormation stack.

Se l'autenticazione dell'utente ha esito positivo, il test restituisce una risposta StatusCode: 200 HTTP, una stringa vuota Message: "" (che altrimenti conterrebbe un motivo dell'errore) e un campo. Response

Nota

Nell'esempio di risposta riportato di seguito, il Response campo è un oggetto JSON che è stato «stringato» (convertito in una stringa JSON flat che può essere utilizzata all'interno di un programma) e contiene i dettagli dei ruoli e delle autorizzazioni dell'utente.

{ "Response":"{\"Policy\":\"{\\\"Version\\\":\\\"2012-10-17\\\",\\\"Statement\\\":[{\\\"Sid\\\":\\\"ReadAndListAllBuckets\\\",\\\"Effect\\\":\\\"Allow\\\",\\\"Action\\\":[\\\"s3:ListAllMybuckets\\\",\\\"s3:GetBucketLocation\\\",\\\"s3:ListBucket\\\",\\\"s3:GetObjectVersion\\\",\\\"s3:GetObjectVersion\\\"],\\\"Resource\\\":\\\"*\\\"}]}\",\"Role\":\"arn:aws:iam::000000000000:role/MyUserS3AccessRole\",\"HomeDirectory\":\"/\"}", "StatusCode": 200, "Message": "" }