es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Boto3 no está generando la URL firmada correcta.

Tengo un caso de uso en el que uso una función lambda para generar URL firmadas para cargar en un cubo S3. También configuro los valores de metadatos al generar la URL firmada, mi versión de boto3 es boto3==1.18.35. Anteriormente, cuando generaba la URL firmada para cargar en el cubo, se veía así:

https://bucket-name.s3.amazonaws.com/scanned-file-list/cf389880-09ff-4301-8fa7-b4054941685b/6919de95-b795-4cac-a2d3-f88ed87a0d08.zip?AWSAccessKeyId=ASIAVK6XU35LOIUAABGC&Signature=xxxx%3D&content-type=application%2Fx-zip-compressed&x-amz-meta-scanid=6919de95-b795-4cac-a2d3-f88ed87a0d08&x-amz-meta-collectorid=2e8672a1-72fd-41cc-99df-1ae3c581d31a&x-amz-security-token=xxxx&Expires=1641318176

Pero ahora la URL se ve así:

https://bucket-name.s3.amazonaws.com/scanned-file-list/f479e304-a2e4-47e7-b1c8-058e3012edac/3d349bab-c814-4aa7-b227-6ef86dd4b0a7.zip?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA2BIILAZ55MATXAGA%2F20220105%2Fus-east-2%2Fs3%2Faws4request&X-Amz-Date=20220105T001950Z&X-Amz-Expires=36000&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-meta-collectorid%3Bx-amz-meta-scan_id&X-Amz-Security-Token=xxxxx&X-Amz-Signature=xxxx

Observa que la URL que ahora genera no tiene el valor correcto para la información de metadatos, es decir, x-amz-meta-collectorid y x-amz-meta-scanid.

La función que uso para generar la URL firmada es la siguiente:

bucket_name = os.environ['S3_UPLOADS_BUCKET_NAME']
metadata = {
'scan_id': scan_id,
'collector_id': collector_id
}

params = {
'Bucket': bucket_name,
'Key': path + file_obj['fileName'],
'ContentType': file_obj.get('contentType') or '',
'Metadata': metadata
}

logger.info('metadata usado para generar la URL: ' + str(metadata))

s3 = boto3.client('s3')
presigned_url = s3.generate_presigned_url('put_object', Params=params, ExpiresIn=36000)
logger.info(f'URL Pre-firmada: {presigned_url}')

return presigned_url

Debido al cambio en la URL, estoy obteniendo un error de SignatureDidNotMatch. ¡Gracias por la ayuda de antemano!

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el cambio en el formato de la URL firmada se debe a la inclusión del parámetro X-Amz-SignedHeaders en el nuevo formato de URL. Este parámetro especifica los encabezados incluidos en el cálculo de la firma y debe contener todos los encabezados especificados en la solicitud original. Para solucionar el problema de que los metadatos no se incluyan en la nueva URL, deberás agregar los encabezados x-amz-meta-collector_id y x-amz-meta-scan_id al parámetro SignedHeaders en tu código.

    Para hacer esto, puedes modificar el diccionario params de la siguiente manera:

    params = {
        'Bucket': nombre_de_bucket,
        'Key': path + file_obj['fileName'],
        'ContentType': file_obj.get('contentType') or '',
        'Metadata': metadata,
        'ACL': 'private' # Agrega este parámetro para especificar el control de acceso para el objeto
    }
    
    # Especifica los encabezados que se incluirán en el cálculo de la firma
    headers = {
        'content-type': params['ContentType'],
        'x-amz-meta-collector_id': metadata['collector_id'],
        'x-amz-meta-scan_id': metadata['scan_id']
    }
    signed_headers = ';'.join(sorted(headers.keys()))
    
    # Genera la URL firmada con los encabezados actualizados
    presigned_url = s3.generate_presigned_url('put_object', Params=params,
                                              ExpiresIn=36000, Headers=headers,
                                              HttpMethod='PUT',
                                              SignedHeaders=signed_headers)
    

    Esto debería generar una URL firmada con los encabezados de metadatos correctos incluidos en el cálculo de la firma, solucionando el error SignatureDidNotMatch.

Comments are closed.