« AWS SDK for .NET » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
Ligne 202 : | Ligne 202 : | ||
options.TokenValidationParameters.AudienceValidator = (audiences, securityToken, validationParameters) => | options.TokenValidationParameters.AudienceValidator = (audiences, securityToken, validationParameters) => | ||
{ | { | ||
// Cognito tokens doesn't have "aud" claim. Instead the audience is set in "client_id" | // This is necessary because Cognito access tokens doesn't have "aud" claim. | ||
var | // Instead the audience is set in "client_id" | ||
if (! | var jwt = (JsonWebToken)securityToken; | ||
if (!jwt.Claims.Any(x => x.Type == "client_id")) | |||
return false; | return false; | ||
return validationParameters.ValidAudience.Contains( | return validationParameters.ValidAudience.Contains(jwt.Claims.First(x => x.Type == "client_id").Value); | ||
}; | }; | ||
}); | }); |
Version du 7 mars 2024 à 14:55
Config
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" } } |
Credentials
This file contains credentials linked to profiles.
∼/.aws/credentials |
[default] aws_access_key_id = ... aws_secret_access_key = ... aws_session_token = ... [Profile1] key = value |
Example .NET applications
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
Load .NET configuration from Secrets Manager
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"]; |
Authentication with Cognito JWT Token
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 |