This file contains the profiles.
∼/.aws/config
|
[default]
region = eu-central-1
[profile Profile1]
sso_start_url = https://my-sso-portal.awsapps.com/start
sso_region = us-west-1
sso_account_id = 111122223333
sso_role_name = SampleRole
region = eu-central-1
output = yaml-stream
services = local-dynamodb
[services local-dynamodb]
dynamodb =
endpoint_url = http://localhost:8000
|
|
aws sso login --profile Profile1
|
Define the AWS_PROFILE in an env var while starting the project.
Properties\launchSettings.json
|
{
"profiles": {
"MyProfile1": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"AWS_PROFILE": "Profile1"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
|
This file contains credentials linked to profiles.
∼/.aws/credentials
|
[default]
aws_access_key_id = ...
aws_secret_access_key = ...
aws_session_token = ...
[Profile1]
key = value
|
|
var ssoCreds = this.LoadSsoCredentials("Profile1");
var token = new AmazonSecurityTokenServiceClient(ssoCreds);
var caller = await token.GetCallerIdentityAsync(new GetCallerIdentityRequest());
this.userId = caller?.UserId.Substring(caller.UserId.IndexOf(":") + 1) ?? string.Empty;
var userNames = await this.GetIamUserNamesAsync(ssoCreds);
var bucketNames = await this.GetS3BucketNames(ssoCreds);
private AWSCredentials LoadSsoCredentials(string profile)
{
var chain = new CredentialProfileStoreChain();
if (!chain.TryGetAWSCredentials(profile, out var credentials))
{
errors.Add($"Failed to find the {profile} profile");
}
// set ClientName and launch a browser window that prompts the SSO user to complete an SSO login
// if the session doesn't already have a valid SSO token.
if (credentials is SSOAWSCredentials ssoCredentials)
{
ssoCredentials.Options.ClientName = "Example-SSO-App";
ssoCredentials.Options.SsoVerificationCallback = args =>
{
Process.Start(new ProcessStartInfo
{
FileName = args.VerificationUriComplete,
UseShellExecute = true
});
};
}
return credentials;
}
private async Task<IReadOnlyCollection<string>> GetIamUserNamesAsync(AWSCredentials ssoCreds)
{
var iamClient = new AmazonIdentityManagementServiceClient(ssoCreds);
var listResponse = await iamClient.ListUsersAsync();
return listResponse.Users.Select(x => x.UserName).ToList();
}
private async Task<IReadOnlyCollection<string>> GetS3BucketNames(AWSCredentials ssoCreds)
{
var s3Client = new AmazonS3Client(ssoCreds);
// Amazon.Runtime.AmazonClientException: 'No RegionEndpoint or ServiceURL configured
// define a default profile in config with a region
var listResponse = await s3Client.ListBucketsAsync();
return listResponse.Buckets.Select(x => x.BucketName).ToList();
}
|
Install the following nuget packages: AWSSDK.Core AWSSDK.SecurityToken AWSSDK.SSO AWSSDK.SSOOIDC
For IAM users: AWSSDK.IdentityManagement
For S3 buckets: AWSSDK.S3
AmazonSecretsManagerConfigurationProvider.cs
|
public class AmazonSecretsManagerConfigurationProvider : ConfigurationProvider
{
private readonly string secretName;
public AmazonSecretsManagerConfigurationProvider(string secretName)
{
this.secretName = secretName;
}
public override void Load()
{
var secret = GetSecret();
Data = JsonSerializer.Deserialize<Dictionary<string, string>>(secret)!;
}
private string GetSecret()
{
var request = new GetSecretValueRequest
{
SecretId = this.secretName
};
using (var client = new AmazonSecretsManagerClient())
{
var response = client.GetSecretValueAsync(request).Result;
return response.SecretString;
}
}
}
|
AmazonSecretsManagerConfigurationSource.cs
|
public class AmazonSecretsManagerConfigurationSource : IConfigurationSource
{
private readonly string secretName;
public AmazonSecretsManagerConfigurationSource(string secretName)
{
this.secretName = secretName;
}
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new AmazonSecretsManagerConfigurationProvider(this.secretName);
}
}
|
ConfigurationBuilderExtensions.cs
|
public static class ConfigurationBuilderExtensions
{
public static void AddAmazonSecretsManager(
this IConfigurationBuilder configurationBuilder, string secretName)
{
var configurationSource = new AmazonSecretsManagerConfigurationSource(secretName);
configurationBuilder.Add(configurationSource);
}
}
|
Program.cs
|
builder.Configuration.AddAmazonSecretsManager("Secret name");
var secretValue = builder.Configuration["Secret key"];
|
Program.cs
|
builder.Services.AddCognitoIdentity();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = builder.Configuration["AWSCognito:Authority"];
options.Audience = builder.Configuration["AWSCognito:UserPoolClientId"];
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateAudience = true
};
options.TokenValidationParameters.AudienceValidator = (audiences, securityToken, validationParameters) =>
{
// This is necessary because Cognito access tokens doesn't have "aud" claim.
// Instead the audience is set in "client_id"
var jwt = (JsonWebToken)securityToken;
if (!jwt.Claims.Any(x => x.Type == "client_id"))
return false;
return validationParameters.ValidAudience.Contains(jwt.Claims.First(x => x.Type == "client_id").Value);
};
});
|
Install the following nuget packages: Amazon.AspNetCore.Identity.Cognito
aws-aspnet-cognito-identity-provider
|
Cognito is not a fully OIDC-compliant provider |