Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide custom AWS Credentials for storage category #3917

Open
oleg-moseyko opened this issue Nov 15, 2024 · 9 comments
Open

Provide custom AWS Credentials for storage category #3917

oleg-moseyko opened this issue Nov 15, 2024 · 9 comments
Labels
feature-request Request a new feature storage Issues related to the Storage category

Comments

@oleg-moseyko
Copy link

oleg-moseyko commented Nov 15, 2024

Is your feature request related to a problem? Please describe.

I would like to upload file to bucket but I can't figure out how to set up Amplify configure by accessKeyId/secretKey with sessionToken which i get from my server:

let tempCredentials = AWSCredentialIdentity(
  accessKey: "accessKeyId",
  secret: "secretKey",
  expiration: nil,
  sessionToken: "sessionToken"
) 
@github-actions github-actions bot added pending-triage Issue is pending triage pending-maintainer-response Issue is pending response from an Amplify team member labels Nov 15, 2024
@edisooon edisooon added storage Issues related to the Storage category question General question labels Nov 15, 2024
@edisooon
Copy link
Member

Hi @oleg-moseyko, thank you for using Amplify! Amplify Storage library manages the tokens retrieved from Cognito to interact with S3 buckets.
You could follow our official documentation to Set up Storage. And if you haven't done yet, you could follow the guide in Quick Start to create Amplify Backend with Authentication.
Let me know if you have any other questions! 😁

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Nov 16, 2024
@oleg-moseyko
Copy link
Author

Hi @edisooon
thank you for sending me the links that I have read many times before
And could you answer the specific question that I asked?

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Nov 18, 2024
@harsh62 harsh62 changed the title configure Provide custom AWS Credentials for storage category Nov 18, 2024
@harsh62 harsh62 added feature-request Request a new feature and removed pending-triage Issue is pending triage question General question pending-maintainer-response Issue is pending response from an Amplify team member labels Nov 18, 2024
Copy link
Contributor

This has been identified as a feature request. If this feature is important to you, we strongly encourage you to give a 👍 reaction on the request. This helps us prioritize new features most important to you. Thank you!

@harsh62
Copy link
Member

harsh62 commented Nov 18, 2024

@oleg-moseyko Providing custom AWS Credentials is currently not supported in the Storage category.

@lon9man
Copy link

lon9man commented Nov 18, 2024

@edisooon, @harsh62

.. my current state is like on harsh62-avatar.

so in 21 century basic developer with basic size mobile application and basic backend to implement basic upload to S3 should:

  • inject Amplify dependency
  • investigate kilometers of the documentation
  • implement very complex (and in whole unneeded for basic developer) complete flow for authentication (AWS resources, IAM roles, user database on AWS, login/signup pages, lambda functions, tons other things)
  • make it work through dozens hours,
  • use Amplify.Storage API
    .. maybe i forgot something

is this way suggested as the best and simplest?
thanks!

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Nov 18, 2024
@harsh62
Copy link
Member

harsh62 commented Nov 18, 2024

@lon9man

From an Amplify perspective, this is considered as an advanced and not very common use case. This is the first feature request we have received for providing custom credentials to storage category.

You could still use the AWS SDK for Swift or Kotlin to achieve your use case, just not using Amplify.

Ideal use case would be:

  1. Federate into the Identity Pools using your custom backend as a provider. You would need to add your backend as a custom provider in identity pools.
  2. Once you have setup the identity pool correctly, use the Storage API without any customization.

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Nov 18, 2024
@oleg-moseyko
Copy link
Author

oleg-moseyko commented Nov 18, 2024

@harsh62
i want to implement multipart upload with progress monitoring

  1. AWS SDK (aws-swift) does not support multipart upload with progress monitoring
  2. AWS SDK (aws-ios) support multipart upload with progress monitoring - BUT is deprecated - if i understand correctly
  3. aws-amplify - support multipart upload with progress monitoring - BUT custom AWS Credentials is currently not supported

how to live with this fucking nonsense?
could you provide example for: Federate into the Identity Pools using your custom backend as a provider.
what is wrong?

       let authConfiguration = AuthCategoryConfiguration(plugins: [
            "awsCognitoAuthPlugin": [
                "UserAgent": "aws-amplify/cli",
                "Version": "0.1.0",
                "IdentityManager": [
                    "Default": []
                ],
                "CredentialsProvider": [
                    "CognitoIdentity": [
                        "Default": [
                            "PoolId": "us-east-1:ca441e53-XXXXX",
                            "Region": "us-east-1"
                        ]
                    ]
                ],
            ]
        ]
        )
        let configuration = AmplifyConfiguration(auth: authConfiguration)
        let authPlugin = AWSCognitoAuthPlugin()
        let storagePlugin = AWSS3StoragePlugin()
       
    
        try Amplify.add(plugin: authPlugin)
        try Amplify.add(plugin: storagePlugin)
        try Amplify.configure(configuration)

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Nov 18, 2024
@harsh62
Copy link
Member

harsh62 commented Nov 19, 2024

@oleg-moseyko ,

Thanks for raising this concern. I understand the frustration when navigating through the complexities of AWS Services and available features. Let’s address your requirements step-by-step. Specifically, I’ll focus on federating into Cognito Identity Pools using a custom backend and developer-provided identity IDs.

I think the following image best reflects your architecture and probably how you should setup everything to access backend resources securely.

image
Reference

Using Developer Authenticated Identities

To implement developer-authenticated identities, the flow involves:

  1. Authenticating the user via your backend.
  2. Using the backend to call GetOpenIdTokenForDeveloperIdentity to generate an identity ID and token.
  3. Using these in your frontend to federate into Cognito Identity Pools with the federateToIdentityPool API.

Below are examples for the backend (in PHP) and the frontend.


Backend Example (PHP)

Using the AWS SDK for PHP, your backend can generate tokens by calling GetOpenIdTokenForDeveloperIdentity. Here’s how it looks:

My PHP skills are not very polished, but this is what I could come up with a little help from Amazon Q

<?php

require 'vendor/autoload.php';

use Aws\CognitoIdentity\CognitoIdentityClient;
use Aws\Exception\AwsException;

class CognitoService
{
    private $client;

    public function __construct($region)
    {
        $this->client = new CognitoIdentityClient([
            'version' => 'latest',
            'region'  => $region,
        ]);
    }

    public function getIdentityToken($identityPoolId, $providerName, $userId)
    {
        try {
            $result = $this->client->getOpenIdTokenForDeveloperIdentity([
                'IdentityPoolId' => $identityPoolId,
                'Logins'         => [
                    $providerName => $userId,
                ],
                'TokenDuration'  => 86400, // Token duration in seconds (optional)
            ]);

            return [
                'identityId' => $result['IdentityId'],
                'token'      => $result['Token'],
            ];
        } catch (AwsException $e) {
            throw new Exception('Error generating token: ' . $e->getMessage());
        }
    }
}

// Usage
$cognitoService = new CognitoService('us-east-1');
$identityPoolId = 'your-identity-pool-id';
$providerName = 'your-auth-provider-name';
$userId = 'unique-user-identifier';

try {
    $credentials = $cognitoService->getIdentityToken($identityPoolId, $providerName, $userId);
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage();
}

This script:

  1. Initializes the AWS Cognito Identity client.
  2. Calls GetOpenIdTokenForDeveloperIdentity to get the IdentityId and Token.
  3. Returns these values, which you’ll send securely to your frontend.

Frontend Example (Swift)

On the frontend, use the federateToIdentityPool API with the identityId and token obtained from your backend. Here’s the Swift implementation:

import Amplify

func federateToIdentityPoolsUsingCustomIdentityId(identityId: String, token: String) async throws {
    guard let authCognitoPlugin = try Amplify.Auth.getPlugin(for: "awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin else {
        fatalError("Unable to get the Auth plugin")
    }

    do {
        let result = try await authCognitoPlugin.federateToIdentityPool(
            withProviderToken: token,
            for: .custom("your-auth-provider-name"),
            options: .init(developerProvidedIdentityID: identityId)
        )
        print("Federation successful with result: \(result)")
    } catch {
        print("Failed to federate to identity pools with error: \(error)")
    }
}

Storage

Once you have completed the above steps, you should be able to use the Storage without any additional configuration, as Amplify under the hood will use the developer provided identity id and token to generate AWS Credentials on your behalf.


Key Considerations

  1. Token Refresh: Amplify does not auto-refresh federated tokens. You’ll need to handle renewal in your app.
  2. Role Permissions: Set up your Identity Pool roles with least-privilege permissions to avoid over-permissioning.

Further Reading

For more details on Developer Authenticated Identities and how they work, check out this blog:
Understanding Amazon Cognito Authentication - Part 2.

If you run into specific issues during implementation, feel free to share more details—I’m happy to help!


Hopefully this should enough to get you over the finish line. 🤞

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Nov 19, 2024
@oleg-moseyko
Copy link
Author

Hi @harsh62
finally i got something like a normal answer from support
thanks
i will investigate

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Nov 19, 2024
@harsh62 harsh62 removed the pending-maintainer-response Issue is pending response from an Amplify team member label Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request a new feature storage Issues related to the Storage category
Projects
None yet
Development

No branches or pull requests

4 participants