aws-amplify / amplify-flutter

A declarative library with an easy-to-use interface for building Flutter applications on AWS.
https://docs.amplify.aws
Apache License 2.0
1.33k stars 248 forks source link

Can't open s3 file/imageUrl It says access denied 403 #2274

Closed emuhaxheri closed 1 year ago

emuhaxheri commented 2 years ago

Description

We are trying to show s3 file/images on mobile app. We integrated the google and email auth from which we got the session and also its token and when we try to open a raw URL of the file/image it says access denied 403. When we try to do it with "Amplify.Storage.getUrl(imageUrl)" it still returns access denied 403.

How should I display an image from s3 bucket?

// This gets thrown in the console

The following HttpExceptionWithStatus was thrown resolving an image codec:
HttpException: Invalid statusCode: 403, uri = https://MY_S3_BUCKET.s3.us-east-2.amazonaws.com/public/https%3A//db9ua1jy8sh8i.cloudfront.net/16a0cdaf-747e-4bc9-b848-e656aa766500/4689ad3e-1b7b-4504-9520-43539fdd9d35.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-
Credential=ASIA2PJ2J7ETZKI2PHNG%2F20221025%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-
Date=20221025T083938Z&X-Amz-Expires=17999&X-Amz-SignedHeaders=host&X-Amz-Security-
Token=IQoJb3JpZ2luX2VjEPn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIHjmTSxlHTFGIMhMmz8nwNsYkqwGGlELk6H%2BvbaAb0TIAiEAsrxnlOTkqNiAUjFbAQULCnRkBAtx42CmO46r1vXDzCEqzQQI0f%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARACGgw3MjAwNjYxODE0MTUiDGbqGfAt4C%2BRmfH%2FjiqhBM1K0reNJ7mcP8oKVbXIWIUC6ALtz4LLRgLAhSMSURuOv8Ei%2Ff9DJytWny9DUo%2B2wPq5WlW%2BdzMCSA2eZdWCxN%2FAyrx34IYumoOHR60gjwlbOf7RpssfxY%2F0LAg8W9btTqX81n061BeBmkdVSUD2dCDxL3LRqnah4NO66Y%2Bok22MuV%2BAWmnmzK9UsTd4y5te7A73F577XsyozsWnSXxuKM8KH3ycmpRqDPZId6mQleolued6KtfLPaqXGx1ItJhiYzyloGm%2B%2BHGxRTjI7aoeF9GYL0YGb5y7HpJm8i0GdnvxxTmgzmwMIOffqpk6w%2BDVVOFohSyUDnsEEOtAJSzkkpzFbg3PASFPHIpA7SewTS%2FPba6Uy1l%2BgEff88YA%2FrF2THus10i7It5OKbhGhtufZVsz3VlAUpE%2FiFHp42O3sUPt9y3nPOtbvdbzgnojWi%2B9OZg6Eg2pct7t9wygWsrqNN5ep1o0DsViEh90w%2FannE5oYo4QTTYo4PrXHsG21TgXpqXcIJnulBm6nEp4o3Ro9nidKSFqy23LQUkEh2HrlCPr6lTBiF%2BehcWcEhzchgJYs%2BKGqwijZGal2%2FYop0DG2BVR4%2BFCT6pWyIfSzE9hY5jxhmc3qOJ3NSgHrrtWzI25tdTXDYVk%2BJFHXLbMw1TM6gKJXHUYH29gqNQMouuiGMx3UcQISwUtw3hE8hqrKrfUVFVPiznHv6yIznhuaIAUIOGUMNK43poGOoUCYXDI28GSD2tE0yuz7M3fG7JdZ2RHe4fhSMyEKcL9lUskAlW5Ci9yCz0LxjSjpFl6%2B2xqSyhP6h4O8rx69BR6gFK6zdWpcG%2FdZ8FGhPpnapbP%2BUbF%2F4Ne3OwkmO0%2BGQ3KKkMeq5vUU5H0mTfKw0sQ04FVjSaf6Ri5Cw8WQYTn7R8ZtNKjL4zJvMl2yfSaS19HBhS%2BbbFg0ye2LoeU5X5ewicGGyAA%2BDc3ZH5NXBtk8ApwJKt8C9ICy%2FtmwfWMGD8KXrm2BUXt32ewJEOUhEn4VkjYCKN9vS4NGK4jdgZF9G9wi2eVqGEZloUhvEFErxUDglS0tV8yK4lenYE8oCBCnxJg1own&
X-Amz-Signature=373b61eefbdcef84a54d5802cbcb457d3b1ca18067c3ed9608ffb3d3212221c0

Categories

Steps to Reproduce

  1. Login
  2. Try to open a protected image url

Screenshots

Screenshot 2022-10-24 at 4 07 12 PM

Platforms

Android Device/Emulator API Level

No response

Environment

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 3.1.0-0.0.pre.966, on macOS 12.5 21G72 darwin-x64, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.60.0)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

• No issues found!

Dependencies

Dart SDK 2.18.0-149.0.dev
Flutter SDK 3.1.0-0.0.pre.966
ambra 1.0.0+2

dependencies:
- amazon_cognito_identity_dart_2 3.0.3 [convert crypto http js]
- amplify_auth_cognito 1.0.0-next.0+6 [amplify_auth_cognito_android amplify_auth_cognito_dart amplify_auth_cognito_ios amplify_core amplify_flutter amplify_secure_storage async flutter flutter_web_plugins meta path plugin_platform_interface]
- amplify_auth_cognito_ios 1.0.0-next.0+4 [amplify_core flutter]
- amplify_authenticator 1.0.0-next.0+4 [amplify_auth_cognito amplify_core amplify_flutter async aws_common collection flutter flutter_localizations intl meta smithy stream_transform]
- amplify_flutter 1.0.0-next.0+4 [amplify_core amplify_datastore_plugin_interface amplify_flutter_android amplify_flutter_ios amplify_secure_storage aws_common collection flutter meta plugin_platform_interface]
- amplify_storage_s3 1.0.0-next.0+3 [amplify_storage_s3_android amplify_storage_s3_ios amplify_core aws_common flutter meta plugin_platform_interface]
- cached_network_image 3.2.1 [flutter flutter_cache_manager octo_image cached_network_image_platform_interface cached_network_image_web]
- carousel_slider 4.1.1 [flutter]
- connectivity_plus 2.3.6+1 [flutter connectivity_plus_platform_interface connectivity_plus_linux connectivity_plus_macos connectivity_plus_web connectivity_plus_windows]
- cupertino_icons 1.0.5
- date_time_picker 2.1.0 [flutter intl]
- device_preview 1.1.0 [flutter flutter_localizations provider device_frame freezed_annotation json_annotation shared_preferences collection]
- drag_and_drop_lists 0.3.3 [flutter]
- file_picker 5.2.1 [flutter flutter_web_plugins flutter_plugin_android_lifecycle plugin_platform_interface ffi path win32]
- filesize 2.0.1
- flutter 0.0.0 [characters collection material_color_utilities meta vector_math sky_engine]
- flutter_colorpicker 0.6.1 [flutter]
- flutter_mentions 2.0.1 [flutter flutter_portal]
- flutter_native_splash 2.2.8 [args flutter flutter_web_plugins html image js lint meta path universal_io xml yaml]
- flutter_signin_button 2.0.0 [flutter font_awesome_flutter]
- flutter_slidable 2.0.0 [flutter]
- flutter_svg 1.1.4 [flutter meta path_drawing vector_math xml]
- get 4.6.3 [flutter]
- google_fonts 2.3.3 [flutter http path_provider crypto]
- http 0.13.5 [async http_parser meta path]
- internet_connection_checker 0.0.1+4
- intl 0.17.0 [clock path]
- overlay_support 2.0.1 [flutter async]
- pin_code_fields 7.4.0 [flutter]
- shared_preferences 2.0.15 [flutter shared_preferences_android shared_preferences_ios shared_preferences_linux shared_preferences_macos shared_preferences_platform_interface shared_preferences_web shared_preferences_windows]
- smooth_page_indicator 1.0.0+2 [flutter]
- syncfusion_flutter_datepicker 20.2.46 [flutter intl syncfusion_flutter_core]
- url_launcher 6.1.6 [flutter url_launcher_android url_launcher_ios url_launcher_linux url_launcher_macos url_launcher_platform_interface url_launcher_web url_launcher_windows]
- uuid 3.0.6 [crypto]
- webview_flutter 3.0.4 [flutter webview_flutter_android webview_flutter_platform_interface webview_flutter_wkwebview]

transitive dependencies:
- amplify_auth_cognito_android 1.0.0-next.0+3 [flutter]
- amplify_auth_cognito_dart 0.2.1 [amplify_core amplify_secure_storage_dart async aws_common aws_signature_v4 built_collection built_value collection convert crypto fixnum http intl js json_annotation meta oauth2 path smithy smithy_aws stream_transform uuid worker_bee]
- amplify_core 1.0.0-next.0+2 [async aws_common aws_signature_v4 collection intl json_annotation logging meta uuid]
- amplify_datastore_plugin_interface 1.0.0-next.0+2 [amplify_core collection flutter meta]
- amplify_flutter_android 1.0.0-next.0 [flutter]
- amplify_flutter_ios 1.0.0-next.0+2 [amplify_core flutter]
- amplify_secure_storage 0.1.2 [amplify_secure_storage_dart async file flutter meta path path_provider]
- amplify_secure_storage_dart 0.1.2 [async aws_common built_collection built_value ffi file js meta path win32 worker_bee]
- amplify_storage_s3_android 1.0.0-next.0 [flutter]
- amplify_storage_s3_ios 1.0.0-next.0 [flutter]
- archive 3.3.1 [crypto path]
- args 2.3.1
- async 2.9.0 [collection meta]
- aws_common 0.2.4 [async collection http2 js json_annotation logging meta stream_transform uuid]
- aws_signature_v4 0.2.2 [async aws_common collection convert crypto json_annotation meta path]
- built_collection 5.1.1
- built_value 8.4.1 [built_collection collection fixnum meta]
- cached_network_image_platform_interface 1.0.0 [flutter flutter_cache_manager]
- cached_network_image_web 1.0.1 [flutter flutter_cache_manager cached_network_image_platform_interface]
- characters 1.2.1
- clock 1.1.0
- collection 1.16.0
- connectivity_plus_linux 1.3.1 [flutter connectivity_plus_platform_interface meta nm]
- connectivity_plus_macos 1.2.4 [connectivity_plus_platform_interface flutter]
- connectivity_plus_platform_interface 1.2.1 [flutter meta plugin_platform_interface]
- connectivity_plus_web 1.2.3 [connectivity_plus_platform_interface flutter_web_plugins flutter]
- connectivity_plus_windows 1.2.2 [connectivity_plus_platform_interface flutter]
- convert 3.0.2 [typed_data]
- crclib 3.0.0 [meta tuple]
- crypto 3.0.2 [typed_data]
- csslib 0.17.2 [source_span]
- dbus 0.7.8 [args ffi meta xml]
- device_frame 1.1.0 [freezed_annotation flutter]
- ffi 2.0.1
- file 6.1.4 [meta path]
- fixnum 1.0.1
- flutter_blurhash 0.7.0 [flutter]
- flutter_cache_manager 3.3.0 [clock collection file flutter http path path_provider pedantic rxdart sqflite uuid]
- flutter_localizations 0.0.0 [flutter intl characters clock collection material_color_utilities meta path vector_math]
- flutter_plugin_android_lifecycle 2.0.7 [flutter]
- flutter_portal 0.4.0 [flutter]
- flutter_web_plugins 0.0.0 [flutter js characters collection material_color_utilities meta vector_math]
- font_awesome_flutter 9.2.0 [flutter]
- freezed_annotation 2.1.0 [collection json_annotation meta]
- html 0.15.0 [csslib source_span]
- http2 2.0.1
- http_parser 4.0.1 [collection source_span string_scanner typed_data]
- image 3.2.0 [archive meta xml]
- js 0.6.4
- json_annotation 4.6.0 [meta]
- lint 1.10.0
- logging 1.1.0
- material_color_utilities 0.1.4
- meta 1.8.0
- nested 1.0.0 [flutter]
- nm 0.5.0 [dbus]
- oauth2 2.0.0 [collection crypto http http_parser]
- octo_image 1.0.2 [flutter flutter_blurhash]
- path 1.8.2
- path_drawing 1.0.1 [vector_math meta path_parsing flutter]
- path_parsing 1.0.1 [vector_math meta]
- path_provider 2.0.11 [flutter path_provider_android path_provider_ios path_provider_linux path_provider_macos path_provider_platform_interface path_provider_windows]
- path_provider_android 2.0.20 [flutter path_provider_platform_interface]
- path_provider_ios 2.0.11 [flutter path_provider_platform_interface]
- path_provider_linux 2.1.7 [ffi flutter path path_provider_platform_interface xdg_directories]
- path_provider_macos 2.0.6 [flutter path_provider_platform_interface]
- path_provider_platform_interface 2.0.4 [flutter platform plugin_platform_interface]
- path_provider_windows 2.1.3 [ffi flutter path path_provider_platform_interface win32]
- pedantic 1.11.1
- petitparser 5.0.0 [meta]
- platform 3.1.0
- plugin_platform_interface 2.1.2 [meta]
- process 4.2.4 [file path platform]
- provider 6.0.3 [collection flutter nested]
- retry 3.1.0
- rxdart 0.27.5
- shared_preferences_android 2.0.12 [flutter shared_preferences_platform_interface]
- shared_preferences_ios 2.1.1 [flutter shared_preferences_platform_interface]
- shared_preferences_linux 2.1.1 [file flutter path path_provider_linux path_provider_platform_interface shared_preferences_platform_interface]
- shared_preferences_macos 2.0.4 [flutter shared_preferences_platform_interface]
- shared_preferences_platform_interface 2.1.0 [flutter plugin_platform_interface]
- shared_preferences_web 2.0.4 [flutter flutter_web_plugins shared_preferences_platform_interface]
- shared_preferences_windows 2.1.1 [file flutter path path_provider_platform_interface path_provider_windows shared_preferences_platform_interface]
- shelf 1.4.0 [async collection http_parser path stack_trace stream_channel]
- sky_engine 0.0.99
- smithy 0.2.0 [async aws_common built_collection built_value collection convert crypto fixnum http_parser intl json_annotation meta path retry shelf typed_data xml]
- smithy_aws 0.2.0 [aws_common aws_signature_v4 built_collection built_value collection convert crclib crypto intl json_annotation meta path smithy xml]
- source_span 1.9.0 [collection path term_glyph]
- sqflite 2.0.3+1 [flutter sqflite_common path]
- sqflite_common 2.2.1+1 [synchronized path meta]
- stack_trace 1.10.0 [path]
- stream_channel 2.1.0 [async]
- stream_transform 2.0.1
- string_scanner 1.1.1 [source_span]
- syncfusion_flutter_core 20.2.46 [vector_math flutter]
- synchronized 3.0.0+2
- term_glyph 1.2.0
- tuple 2.0.1
- typed_data 1.3.1 [collection]
- universal_io 2.0.4 [collection crypto meta typed_data]
- url_launcher_android 6.0.19 [flutter url_launcher_platform_interface]
- url_launcher_ios 6.0.17 [flutter url_launcher_platform_interface]
- url_launcher_linux 3.0.1 [flutter url_launcher_platform_interface]
- url_launcher_macos 3.0.1 [flutter url_launcher_platform_interface]
- url_launcher_platform_interface 2.1.1 [flutter plugin_platform_interface]
- url_launcher_web 2.0.13 [flutter flutter_web_plugins url_launcher_platform_interface]
- url_launcher_windows 3.0.1 [flutter url_launcher_platform_interface]
- vector_math 2.1.2
- webview_flutter_android 2.9.5 [flutter webview_flutter_platform_interface]
- webview_flutter_platform_interface 1.9.2 [flutter meta plugin_platform_interface]
- webview_flutter_wkwebview 2.9.3 [flutter path webview_flutter_platform_interface]
- win32 3.0.0 [ffi]
- worker_bee 0.1.1 [async aws_common built_collection built_value collection js meta path stack_trace stream_channel stream_transform]
- xdg_directories 0.2.0+2 [meta path process]
- xml 6.1.0 [collection meta petitparser]
- yaml 3.1.1 [collection source_span string_scanner]

Device

Iphone 14 pro max (simulator)

OS

iOS 16.0

Deployment Method

Amplify CLI

CLI Version

10.0.0

Additional Context

No response

Amplify Config

const amplifyconfig = ''' { "UserAgent": "aws-amplify-cli/2.0", "Version": "1.0", "auth": { "plugins": { "awsCognitoAuthPlugin": { "UserAgent": "aws-amplify-cli/0.1.0", "Version": "0.1.0", "IdentityManager": { "Default": {} }, "CredentialsProvider": { "CognitoIdentity": { "Default": { "PoolId": "------", "Region": "us-east-1" } } }, "CognitoUserPool": { "Default": { "PoolId": "------", "AppClientId": "------", "Region": "us-east-1" } }, "Auth": { "Default": { "OAuth": { "WebDomain": "------", "AppClientId": "------", "SignInRedirectURI": "------", "SignOutRedirectURI": "------", "Scopes": [ "aws.cognito.signin.user.admin", "email", "openid", "profile" ] }, "authenticationFlowType": "CUSTOM_AUTH", "socialProviders": [ "GOOGLE" ], "usernameAttributes": [ "EMAIL" ], "signupAttributes": [ "NAME", "EMAIL" ], "passwordProtectionSettings": { "passwordPolicyMinLength": 8, "passwordPolicyCharacters": [] }, "mfaConfiguration": "OFF", "mfaTypes": [], "verificationMechanisms": [] } }, "S3TransferUtility": { "Default": { "Bucket": "------", "Region": "us-east-2" } } } } }, "storage": { "plugins": { "awsS3StoragePlugin": { "bucket": "------", "region": "us-east-2", "defaultAccessLevel": "guest" } } } }''';

HuiSF commented 2 years ago

Looking at the generated url (shown in your screenshot), it doesn't seem to be a correct url at all. Can you share the code snippet of how you are invoking the getUrl API and parameters?

In addition, have you configured Storage category using Amplify CLI, or are you trying to use the Storage category with your existing S3 resource?

Are you trying to use Storage plugin with CloudFront proxied S3 bucket? (this is not currently supported.)

emuhaxheri commented 2 years ago

Hello! @HuiSF!! below you will find my code snippets and my answers to your questions.

No I haven't configured the storage category using Amplify CLI because I'm importing the storage package from an existing web app and as per the Storage plugin being with CloudFront proxied S3 bucket the answer is yes, I'm using that.

How should I proceed with this?

// Getting the url from the package

Future<GetUrlResult> getImageUrlFromS3(String fileKey) async {
    try {
      final result = await Amplify.Storage.getUrl(
        key: fileKey,
      );
      // print('image url: ${result.url}');
      return result;
    } on StorageException catch (e) {
      print('error down file: $e');
      throw errorSnackBar('Oopss', e.toString());
    }
  }
// Implementing the function in the UI as a FutureBuilder
child: FutureBuilder<GetUrlResult>(
  future: projectDetailsController
      .getImageUrlFromS3(
    task!.files![index].path!,
  ),
  builder: (context, snapshot) {
    final result = snapshot.data;
    print(result);
    if (result == null) {
      return const SizedBox();
    } else {
      return Container(
        width: 300,
        height: 300,
        decoration: BoxDecoration(
          image: DecorationImage(
            image:
                CachedNetworkImageProvider(
              result.url,
            ),
            fit: BoxFit.fill,
          ),
        ),
      );
    }
  },
),
// What we get from "task!.files![index].path!" 

 https://db9ua1jy8sh8i.cloudfront.net/16a0cdaf-747e-4bc9-b848-e656aa766500/4689ad3e-1b7b-4504-9520-43539fdd9d35.jpeg
HuiSF commented 2 years ago

Thanks for the follow up @emuhaxheri It sounds like that you have a s3 bucket, that hosts some images files, your Web App renders the images from it via CloudFront. And you are trying to do the same thing for your Flutter built mobile App, is that correct? Unfortunately the Storage S3 plugin doesn't work with CloudFront, it requires direct interaction with the S3 bucket itself.

All Amplify Storage S3 plugin APIs requires object key that identifies the "location" of the object in your bucket. In your code example you are trying to getUrl with a CloudFront url, that won't work.

Can you look up what's the actual object key in your bucket that below url points to?

https://db9ua1jy8sh8i.cloudfront.net/16a0cdaf-747e-4bc9-b848-e656aa766500/4689ad3e-1b7b-4504-9520-43539fdd9d35.jpeg

There may be a workaround for your use case.

akotorri commented 2 years ago

Hello @HuiSF I'm a colleague of @emuhaxheri and I've taken over this task,

I've been looking for the object key for the files and I can't seem to determine what it actually is but I can suspect that it is the fileName which would be this "4689ad3e-1b7b-4504-9520-43539fdd9d35.jpeg", as a workaround I've been thinking of constructing the url myself by have the provided url as the starting point then add the signature and the token on it, would that work? or do you have any cleaner other workarounds in mind? If so please do tell, cuz I would prefer doing that then doing what I suggested :)

A question that I would like to ask is that does what you said correspond with uploading a file as well, or is it just for "getUrl()" function?

Jordan-Nelson commented 2 years ago

I'm importing the storage package from an existing web app

How are you getting the URL to display these in the web app? Are you using Amplify?

HuiSF commented 1 year ago

Hi @akotorri @emuhaxheri I'm sorry that I lost track of this thread.

but I can suspect that it is the fileName which would be this "4689ad3e-1b7b-4504-9520-43539fdd9d35.jpeg"

You meant you cannot view the bucket at all to identity the object key that you were trying to getUrl with?

as a workaround I've been thinking of constructing the url myself by have the provided url as the starting point then add the signature and the token on it, would that work?

Still, were you trying to use a pre-existing s3 bucket with Amplify Storage? I'm not sure how to answer your question precisely with the information I gathered so far.

I would like to ask is that does what you said correspond with uploading a file as well, or is it just for "getUrl()" function?

Yes that's correct, Amplify Storage S3 plugin has a set of predefined auth rules associated with file access level as well, if you were trying to use pre-existing s3 bucket without conforming the auth set up, you may need extra steps to make it work.

Please let me know.

Jordan-Nelson commented 1 year ago

@akotorri @emuhaxheri - If you are still facing this issue please take a look at @HuiSF's questions above.

ALi4576 commented 1 year ago

I am having the same issue, can someone help?

SettiNitesh commented 11 months ago
image

I am getting this issue in android actually i have uploaded a image from ios in android dit is not getting .