private StoredInfo SelectAndStoreProfileForRole(string assertion, IList <SAMLCredential> roleSet, string preselectedPrincipalAndRoleARN) { string roleArn = preselectedPrincipalAndRoleARN; if (!this.TestPreselectedRoleAvailable(preselectedPrincipalAndRoleARN, roleSet.Select(arn => arn.Value).ToList())) { if (roleSet.Count == 1) { roleArn = roleSet.First().Value; base.WriteVerbose($"Only one role available, pre-selecting role ARN {preselectedPrincipalAndRoleARN}"); } else { if (AwsAccountId != null && AwsAccountId.Length > 0) { roleSet = roleSet.Where(r => AwsAccountId.Contains(r.PrincipalArn.AccountId, StringComparer.OrdinalIgnoreCase)).ToList(); } var width = this.Host.UI.RawUI.WindowSize.Width - 4; // $MenuOptions.MaxWidth - 4 List <char> okchars = new List <char>(); for (char c = 'A'; c <= 'Z'; c++) { okchars.Add(c); // A - Z } for (char c = '0'; c <= '9'; c++) { okchars.Add(c); // 0 - 9 } for (char c = '!'; c <= '/'; c++) { okchars.Add(c); // ! - / } for (char c = ':'; c <= '>'; c++) { okchars.Add(c); // : - > } for (char c = '['; c <= '_'; c++) { okchars.Add(c); // [ - _ } for (char c = '{'; c <= '~'; c++) { okchars.Add(c); // { - ~ } Collection <ChoiceDescription> collection = new Collection <ChoiceDescription>(); int idx = 0; foreach (var cred in roleSet.OrderBy(r => r.RoleArn.AccountId).ThenBy(r => r.RoleArn.Resource)) { string label; if (roleSet.Count <= okchars.Count) { label = $"&{okchars[idx]} - {cred.RoleArn.Resource}"; label = NewSpaceDelimitedText(label, width) + "."; } else { label = cred.RoleArn.Resource; } collection.Add(new ChoiceDescription(label, cred.Value)); idx++; } bool userChooses = true; int idxDefault = 0; if (!string.IsNullOrWhiteSpace(this.HelpFindResource)) { var fnd = collection.Where(r => r.Label.IndexOf(this.HelpFindResource, StringComparison.InvariantCultureIgnoreCase) >= 0).ToArray(); if (fnd.Length == 1 && this.SingleMatch) { WriteVerbose($"Found single match of role with the value '{this.HelpFindResource}', using that specific role only."); roleArn = collection[collection.IndexOf(fnd[0])].HelpMessage; userChooses = false; } else if (fnd.Length >= 1) { idxDefault = collection.IndexOf(fnd[0]); // Pre-select the first role found with the HelpFindResource's value } } if (userChooses) { int index = base.Host.UI.PromptForChoice(Lang.SelectRoleCaption, Lang.SelectRoleMessage, collection, idxDefault); roleArn = collection[index].HelpMessage; } } } if (string.IsNullOrEmpty(roleArn)) { this.ThrowExecutionError(Lang.ErrorNoRoleSelected, this); } var role = roleSet.FirstOrDefault(r => r.Value.Equals(roleArn, StringComparison.OrdinalIgnoreCase)); this.WriteVerbose($"Getting [{role.PrincipalArn}] tokens using [{role.RoleArn}]"); var aRole = this.ExecuteCmdletInPipeline <dynamic>("Use-STSRoleWithSAML", new { SAMLAssertion = assertion, RoleArn = role.RoleArn.OriginalString, PrincipalArn = role.PrincipalArn.OriginalString, DurationInSeconds = 60 * TokenDurationInMinutes }).FirstOrDefault(); base.WriteVerbose($"Saving to profile '{this.StoreAs ?? role.RoleArn.Resource}'."); var home = this.GetVariableValue("HOME") as string; _ = this.ExecuteCmdletInPipeline("Set-AWSCredential", new { ProfileLocation = Path.Combine(home, ".aws", "credentials"), AccessKey = aRole.Credentials.AccessKeyId, SecretKey = aRole.Credentials.SecretAccessKey, aRole.Credentials.SessionToken, StoreAs = this.StoreAs ?? role.RoleArn.Resource }); base.WriteVerbose($"Stored AWS Credentials as {this.StoreAs ?? role.RoleArn.Resource}.\r\nUse 'Set-AWSCredentials -ProfileName {this.StoreAs ?? role.RoleArn.Resource}' to load this profile and obtain temporary AWS credentials."); return(new StoredInfo { AssertionDoc = assertion, Expires = aRole.Credentials.Expiration, PrincipalArn = role.PrincipalArn, RoleArn = role.RoleArn, StoreAs = this.StoreAs ?? role.RoleArn.Resource }); }
protected override void ProcessRecord() { try { NetworkCredential networkCredential = null; if (this.Credential != null) { base.WriteVerbose(Lang.UseGivenNetworkCredentials); networkCredential = this.Credential.GetNetworkCredential(); } ServicePointManager.SecurityProtocol = this.SecurityProtocol; IbmIam2AwsSamlScreenScrape aad2Aws = new IbmIam2AwsSamlScreenScrape(this) { ErrorClass = this.ErrorClass, ErrorElement = this.ErrorElement, Proxy = this.GetWebProxy(), Credentials = networkCredential, Logger = (m, t) => { switch (t) { case LogType.Debug: this.WriteVerbose(m); break; case LogType.Info: this.Host.UI.WriteLine(m); //_cmdlet.WriteInformation(new InformationRecord(m, "")); break; case LogType.Warning: this.WriteWarning(m); break; case LogType.Error: this.WriteError(new ErrorRecord(new Exception(m), "5000", ErrorCategory.NotSpecified, this)); break; } } }; var assertion = aad2Aws.RetrieveSAMLAssertion(IbmIamEndpoint); var roles = aad2Aws.GetRolesFromAssertion(); if (AwsAccountId != null && AwsAccountId.Length > 0) { roles = roles.Where(r => AwsAccountId.Contains(r.PrincipalArn.AccountId, StringComparer.OrdinalIgnoreCase)).ToArray(); } foreach (var role in roles) { this.WriteObject(role); } } catch (IbmIamErrorException ex) { base.WriteError(new ErrorRecord(ex, ex.ErrorCode, ErrorCategory.NotSpecified, this)); } catch (IbmIamPasswordExpiredException ex) { base.WriteError(new ErrorRecord(ex, "PasswordExpired", ErrorCategory.AuthenticationError, this)); } catch (Exception ex) { base.WriteError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.CurrentCulture, Lang.ErrorUnableSetCredentials, ex.Message), ex), "ArgumentException", ErrorCategory.InvalidArgument, this)); } }
protected override void ProcessRecord() { try { string preselectedPrincipalAndRoleARN = null; NetworkCredential networkCredential = null; if (this.Credential != null) { base.WriteVerbose(Lang.UseGivenNetworkCredentials); networkCredential = this.Credential.GetNetworkCredential(); } bool hasPrinARN = this.ParameterWasBound(nameof(PrincipalARN)) && !string.IsNullOrWhiteSpace(this.PrincipalARN); bool hasRoleARN = this.ParameterWasBound(nameof(RoleARN)) && !string.IsNullOrWhiteSpace(this.RoleARN); if (hasPrinARN != hasRoleARN) { this.ThrowExecutionError(Lang.PrincipalRequiredWithRole, this); } if (hasPrinARN & hasRoleARN) { preselectedPrincipalAndRoleARN = $"{this.RoleARN},{this.PrincipalARN}"; } ServicePointManager.SecurityProtocol = this.SecurityProtocol; IbmIam2AwsSamlScreenScrape ibm2Aws = new IbmIam2AwsSamlScreenScrape(this) { ErrorClass = this.ErrorClass, ErrorElement = this.ErrorElement, Proxy = this.GetWebProxy(), Credentials = networkCredential, Logger = (m, t) => { switch (t) { case LogType.Debug: this.WriteVerbose(m); break; case LogType.Info: this.Host.UI.WriteLine(m); //_cmdlet.WriteInformation(new InformationRecord(m, "")); break; case LogType.Warning: this.WriteWarning(m); break; case LogType.Error: this.WriteError(new ErrorRecord(new Exception(m), "5000", ErrorCategory.NotSpecified, this)); break; } } }; var assertion = ibm2Aws.RetrieveSAMLAssertion(IbmIamEndpoint); var roles = ibm2Aws.GetRolesFromAssertion(); if (this.StoreAllRoles) { if (AwsAccountId != null && AwsAccountId.Length > 0) { roles = roles.Where(r => AwsAccountId.Contains(r.PrincipalArn.AccountId, StringComparer.OrdinalIgnoreCase)).ToArray(); } foreach (var role in roles) { this.WriteVerbose($"Getting [{role.PrincipalArn}] tokens using [{role.RoleArn}]"); try { var aRole = this.ExecuteCmdletInPipeline <dynamic>("Use-STSRoleWithSAML", new { SAMLAssertion = ibm2Aws.Assertion, RoleArn = role.RoleArn.OriginalString, PrincipalArn = role.PrincipalArn.OriginalString, DurationInSeconds = 60 * this.TokenDurationInMinutes }).FirstOrDefault(); this.WriteObject(new StoredInfo { AssertionDoc = assertion, Expires = aRole.Credentials.Expiration, PrincipalArn = role.PrincipalArn, RoleArn = role.RoleArn, StoreAs = this.StoreAs ?? role.RoleArn.Resource }); base.WriteVerbose($"Saving role '{role.Value}' to profile '{role.RoleArn.Resource}'."); var home = this.GetVariableValue("HOME") as string; _ = this.ExecuteCmdletInPipeline("Set-AWSCredential", new { ProfileLocation = Path.Combine(home, ".aws", "credentials"), AccessKey = aRole.Credentials.AccessKeyId, SecretKey = aRole.Credentials.SecretAccessKey, aRole.Credentials.SessionToken, StoreAs = role.RoleArn.Resource }); } //catch (ExpiredTokenException ex) //{ // this.WriteVerbose($"Could not Assume Role: {role.RoleArn.Resource}"); // this.WriteVerbose("Attempting to Refresh Token"); // // Updating Assertion Document // sAMLAssertion = _awsAuthController.GetSAMLAssertion(endpoint.EndpointUri.ToString(), networkCredential, endpoint.AuthenticationType.ToString()); // this.WriteVerbose("Retrying this operation"); // creds = AssumeRole(sts, config, role.RoleArn.Resource, sAMLAssertion, role, this.TokenDurationInMinutes); // this.WriteVerbose($"RetryResult: {creds}"); //} catch (Exception ex) { this.WriteError(new ErrorRecord(ex, "5000", ErrorCategory.NotSpecified, this)); } } } else { StoredInfo sendToPipeline = this.SelectAndStoreProfileForRole(assertion, roles, preselectedPrincipalAndRoleARN); base.WriteObject(sendToPipeline); } } catch (IbmIamErrorException ex) { base.WriteError(new ErrorRecord(ex, ex.ErrorCode, ErrorCategory.NotSpecified, this)); } catch (IbmIamPasswordExpiredException ex) { base.WriteError(new ErrorRecord(ex, "PasswordExpired", ErrorCategory.AuthenticationError, this)); } catch (Exception ex) { base.WriteError(new ErrorRecord(new ArgumentException("Unable to set credentials: " + ex.Message, ex), "ArgumentException", ErrorCategory.InvalidArgument, this)); } }