/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.Runtime.Internal; using Amazon.Runtime.Internal.Util; using Amazon.Runtime.SharedInterfaces; using System; using System.Globalization; using System.Net; namespace Amazon.Runtime { /// /// AWS Credentials that automatically refresh by calling AssumeRole on /// the Amazon Security Token Service. /// public class AssumeRoleAWSCredentials : RefreshingAWSCredentials { private RegionEndpoint DefaultSTSClientRegion = RegionEndpoint.USEast1; private Logger _logger = Logger.GetLogger(typeof(AssumeRoleAWSCredentials)); /// /// The credentials of the user that will be used to call AssumeRole. /// public AWSCredentials SourceCredentials { get; private set; } /// /// The Amazon Resource Name (ARN) of the role to assume. /// public string RoleArn { get; private set; } /// /// An identifier for the assumed role session. /// public string RoleSessionName { get; private set; } /// /// Options to be used in the call to AssumeRole. /// public AssumeRoleAWSCredentialsOptions Options { get; private set; } /// /// Constructs an AssumeRoleAWSCredentials object. /// /// The credentials of the user that will be used to call AssumeRole. /// The Amazon Resource Name (ARN) of the role to assume. /// An identifier for the assumed role session. public AssumeRoleAWSCredentials(AWSCredentials sourceCredentials, string roleArn, string roleSessionName) : this(sourceCredentials, roleArn, roleSessionName, new AssumeRoleAWSCredentialsOptions()) { } /// /// Constructs an AssumeRoleAWSCredentials object. /// /// The credentials of the user that will be used to call AssumeRole. /// The Amazon Resource Name (ARN) of the role to assume. /// An identifier for the assumed role session. /// Options to be used in the call to AssumeRole. public AssumeRoleAWSCredentials(AWSCredentials sourceCredentials, string roleArn, string roleSessionName, AssumeRoleAWSCredentialsOptions options) { if (options == null) { throw new ArgumentNullException("options"); } SourceCredentials = sourceCredentials; RoleArn = roleArn; RoleSessionName = roleSessionName; Options = options; // Make sure to fetch new credentials well before the current credentials expire to avoid // any request being made with expired credentials. PreemptExpiryTime = TimeSpan.FromMinutes(5); } protected override CredentialsRefreshState GenerateNewCredentials() { var region = FallbackRegionFactory.GetRegionEndpoint() ?? DefaultSTSClientRegion; ICoreAmazonSTS coreSTSClient; try { var stsConfig = ServiceClientHelpers.CreateServiceConfig(ServiceClientHelpers.STS_ASSEMBLY_NAME, ServiceClientHelpers.STS_SERVICE_CONFIG_NAME); stsConfig.RegionEndpoint = region; if (Options != null && Options.ProxySettings != null) { stsConfig.SetWebProxy(Options.ProxySettings); } coreSTSClient = ServiceClientHelpers.CreateServiceFromAssembly( ServiceClientHelpers.STS_ASSEMBLY_NAME, ServiceClientHelpers.STS_SERVICE_CLASS_NAME, SourceCredentials, stsConfig); } catch (Exception e) { var msg = string.Format(CultureInfo.CurrentCulture, "Assembly {0} could not be found or loaded. This assembly must be available at runtime to use Amazon.Runtime.AssumeRoleAWSCredentials.", ServiceClientHelpers.STS_ASSEMBLY_NAME); var exception = new InvalidOperationException(msg, e); Logger.GetLogger(typeof(AssumeRoleAWSCredentials)).Error(exception, exception.Message); throw exception; } var credentials = coreSTSClient.CredentialsFromAssumeRoleAuthentication(RoleArn, RoleSessionName, Options); _logger.InfoFormat("New credentials created for assume role that expire at {0}", credentials.Expiration.ToString("yyyy-MM-ddTHH:mm:ss.fffffffK", CultureInfo.InvariantCulture)); return new CredentialsRefreshState(credentials, credentials.Expiration); } } }