I need to access an AWS S3 bucket and DynamoDB securely using user pools and identity pools. I can log in a user:
public static async Task<bool> SimpleLogin(string username, string password)
{
bool loginSuccess = false;
string accessToken;
UserCredentials user1 = new UserCredentials() { Username = username, Password = password };
//taken from this article https://docs.amazonaws.cn/en_us/sdk-for-net/v3/developer-guide/cognito-authentication-extension.html
var creds = new BasicAWSCredentials(IAMAccessID, IAMSecretID);
AmazonCognitoIdentityProviderClient provider =
new AmazonCognitoIdentityProviderClient(creds, RegionEndpoint.EUWest2);
CognitoUserPool userPool = new CognitoUserPool(poolID, clientID, provider);
CognitoUser user = new CognitoUser(user1.Username, clientID, userPool, provider);
InitiateSrpAuthRequest authRequest = new InitiateSrpAuthRequest()
{
Password = user1.Password
};
try
{
AuthFlowResponse authResponse = await user.StartWithSrpAuthAsync(authRequest).ConfigureAwait(false);
if (authResponse.AuthenticationResult != null)
{
Debug.WriteLine("User successfully authenticated.");
loginSuccess = true;
}
else
{
Debug.WriteLine("Error in authentication process.");
loginSuccess = false;
}
}
catch (Amazon.CognitoIdentityProvider.Model.NotAuthorizedException nae)
{
//bad username or password
loginSuccess = false;
}
catch (Exception ex)
{
//any other exception
}
return loginSuccess;
}
But, as I understand it, the next step is to use the access token returned to access and identity pool so that I can then access the S3 bucket and DynamoDB. I cannot find any examples that do this.
This code creates Cognito credentials and attempts to log into the bucket:
CognitoAWSCredentials c = new CognitoAWSCredentials(identityPoolID, RegionEndpoint.EUWest2);
using (var client = new AmazonS3Client(c, RegionEndpoint.EUWest2))
{
var dir = new S3DirectoryInfo(client, "recordings", "924f22fb-2694-4fce-b85a-47b1c59b8466");
foreach (IS3FileSystemInfo file in dir.GetFileSystemInfos())
{
Debug.WriteLine(file.Name);
Debug.WriteLine(file.Extension);
Debug.WriteLine(file.LastWriteTime);
}
ListBucketsResponse response =
await client.ListBucketsAsync(new ListBucketsRequest()).ConfigureAwait(false);
foreach (S3Bucket bucket in response.Buckets)
{
Debug.WriteLine(bucket.BucketName);
}
}
But, I’m having two problems with this. First, I’m getting a 400 error when creating the S3DirectoryInfo object, and secondly when I’m creating the identity pool credentials, they’re not asking for an access token, which doesn’t make sense to me.
2
Answers
"I cannot find any examples that do this"
Looks like you want an example that shows how to use temp creds to access AWS Services. One way is to use IAM and STS vs Cognito.
There is an example that performs these tasks using IAM and STS:
Create a user who has no permissions.
Create a role that grants permission to list Amazon S3 buckets for the account.
Add a policy to let the user assume the role.
Assume the role and list Amazon S3 buckets using temporary credentials.
Delete the policy, role, and user.
This use case is documented in the new AWS Code Library in different programming langauges, including C#. The Code Library has 100s of unit tested examples that work.
You can access this use case in C# here:
https://docs.aws.amazon.com/code-library/latest/ug/iam_example_iam_Scenario_CreateUserAssumeRole_section.html
Cognito example
If you want to use Cognito to get an athent token, the code lib also has that example in C#. See this URL:
https://docs.aws.amazon.com/code-library/latest/ug/cognito-identity-provider_example_cognito-identity-provider_Scenario_SignUpUserWithMfa_section.html
UPDATE ON THE .NET MVP CODE
When you stated it did not run, I tested it in Visual Studio 2022. You can get all of the code, project files, etc from Github here:
https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/Cognito
Once you get this code from Github, open it, follow the instructions, specify the pool id and client id that the program requires, it runs fine. See this illustration.
NOTE: As I stated, every single program in the code library has gone through extensive unit testing to ensure they work.
Let me address your comments one at a time:
When you are trying to run the examples, do you pull the entire example application from GitHub or do you just copy and paste from the Code Library? The code library focuses on the code that actually performs the API call. To successfully run an example, you have to get the whole thing from GitHub.
Instantiating a client object for any of the examples can be done with no parameters if the default user has been set up properly. Setting up the credentials properly is described in GitHub at the language level.
The Cognito_MVP namespace is the namespace of the basic scenario that shows how to use Cognito. Again, to find it, you have to look at the entire example on GitHub rather than the excerpt that is published in the code catalog.