

The AWS SDK for .NET V3 has entered maintenance mode.

We recommend that you migrate to [AWS SDK for .NET V4](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/welcome.html). For additional details and information on how to migrate, please refer to our [maintenance mode announcement](https://aws.amazon.com/blogs/developer/aws-sdk-for-net-v3-maintenance-mode-announcement/).

# Advanced authentication and authorization with the AWS SDK for .NET
Advanced auth

The topics in this section provide information about advanced techniques for authentication and authorization in your AWS SDK for .NET application.

**Topics**
+ [Single sign-on](sso.md)

# Single sign-on with the AWS SDK for .NET
Single sign-onSingle sign-on with the AWS SDK for .NET

Added information about single sign-on (SSO) when using the AWS SDK for .NET.

AWS IAM Identity Center is a cloud-based single sign-on (SSO) service that makes it easy to centrally manage SSO access to all of your AWS accounts and cloud applications. For full details, see the [IAM Identity Center User Guide](https://docs.aws.amazon.com/singlesignon/latest/userguide/).

If you're unfamiliar with how an SDK interacts with IAM Identity Center, see the following information.

## High-level pattern of interaction


At a high level, SDKs interact with IAM Identity Center in a manner similar to the following pattern:

1. IAM Identity Center is configured, typically through the [IAM Identity Center console](https://console.aws.amazon.com/singlesignon), and an SSO user is invited to participate.

1. The shared AWS `config` file on the user's computer is updated with SSO information.

1. The user signs in through IAM Identity Center and is given short-term credentials for the AWS Identity and Access Management (IAM) permissions that have been configured for them. This sign-in can be initiated through a non-SDK tool like the AWS CLI, or programmatically through a .NET application.

1. The user proceeds to do their work. When they run other applications that are using SSO, they don't need to sign in again to open the applications.

The rest of this topic provides reference information for setting up and using AWS IAM Identity Center. It provides supplemental and more advanced information than the basic SSO setup in [Configure SDK authentication](creds-idc.md). If you're new to SSO on AWS, you might want to look at that topic first for fundamental information, and then at the following tutorials to see SSO in action:
+ [Tutorial: .NET application only](sso-tutorial-app-only.md)
+ [Tutorial: AWS CLI and .NET application](sso-tutorial-cli-and-app.md)

This topic contains the following sections:
+ [Prerequisites](#sso-prereq)
+ [Setting up an SSO profile](#sso-profiles)
+ [Generating and using SSO tokens](#sso-generate-use-token-overview)
+ [Additional resources](#sso-resources)
+ [Tutorials](#sso-tutorial-links)

## Prerequisites


Before using IAM Identity Center, you must perform certain tasks, such as choosing an identity source and configuring the relevant AWS accounts and applications. For additional information, see the following:
+ For general information about these tasks, see [Getting started](https://docs.aws.amazon.com/singlesignon/latest/userguide/getting-started.html) in the *IAM Identity Center User Guide*.
+ For specific task examples, see the list of tutorials at the end of this topic. However, be sure to review the information in this topic before trying out the tutorials.

## Setting up an SSO profile


After IAM Identity Center is [configured](https://docs.aws.amazon.com/singlesignon/latest/userguide/getting-started.html) in the relevant AWS account, a named profile for SSO must be added to the user's shared AWS `config` file. This profile is used to connect to the *[AWS access portal](https://docs.aws.amazon.com/singlesignon/latest/userguide/using-the-portal.html)*, which returns short-term credentials for the IAM permissions that have been configured for the user.

The shared `config` file is typically named `%USERPROFILE%\.aws\config` in Windows and `~/.aws/config` in Linux and macOS. You can use your preferred text editor to add a new profile for SSO. Alternatively, you can use the `aws configure sso` command. For more information about this command, see [Configuring the AWS CLI to use IAM Identity Center](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) in the *AWS Command Line Interface User Guide*.

The new profile is similar to the following:

```
[profile my-sso-profile]
sso_start_url = https://my-sso-portal.awsapps.com/start
sso_region = us-west-2
sso_account_id = 123456789012
sso_role_name = SSOReadOnlyRole
```

The settings for the new profile are defined below. The first two settings define the AWS access portal. The other two settings are a pair that, taken together, define the permissions that have been configured for a user. All four settings are required.

**`sso_start_url`**  
The URL that points to the organization's [AWS access portal](https://docs.aws.amazon.com/singlesignon/latest/userguide/using-the-portal.html). To find this value, open the [IAM Identity Center console](https://console.aws.amazon.com/singlesignon), choose **Settings**, and find **portal URL**.

**`sso_region`**  
The AWS Region that contains the access portal host. This is the Region that was selected as you enabled IAM Identity Center. It can be different from the Regions that you use for other tasks.  
For a complete list of the AWS Regions and their codes, see [Regional Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints) in the *Amazon Web Services General Reference*.

**`sso_account_id`**  
The ID of an AWS account that was added through the AWS Organizations service. To see the list of available accounts, go to the [IAM Identity Center console](https://console.aws.amazon.com/singlesignon) and open the **AWS accounts** page. The account ID that you choose for this setting will correspond to the value that you plan to give to the `sso_role_name` setting, which is shown next.

**`sso_role_name`**  
The name of an IAM Identity Center permission set. This permission set defines the permissions that a user is given through IAM Identity Center.  
The following procedure is one way to find the value for this setting.  

1. Go to the [IAM Identity Center console](https://console.aws.amazon.com/singlesignon) and open the **AWS accounts** page.

1. Choose an account to display its details. The account you choose will be the one that contains the SSO user or group that you want to give SSO permissions to.

1. Look at the list of users and groups that are assigned to the account and find the user or group of interest. The permission set that you specify in the `sso_role_name` setting is one of the sets associated with this user or group.
When giving a value to this setting, use the name of the permission set, not the Amazon Resource Name (ARN).  
Permission sets have IAM policies and custom-permissions policies attached to them. For more information, see [Permission sets](https://docs.aws.amazon.com/singlesignon/latest/userguide/permissionsets.html) in the *IAM Identity Center User Guide*.

## Generating and using SSO tokens


To use SSO, a user must first generate a temporary token and then use that token to access appropriate AWS applications and resources. For .NET applications, you can use the following methods to generate and use these temporary tokens:
+ Create .NET applications that generate a token first, if necessary, and then use the token.
+ Generate a token with the AWS CLI and then use the token in .NET applications.

These methods are described in the following sections and demonstrated in the [tutorials](#sso-tutorial-links).

**Important**  
Your application must reference the following NuGet packages so that SSO resolution can work:  
`AWSSDK.SSO`
`AWSSDK.SSOOIDC`
Failure to reference these packages will result in a *runtime* exception.

### .NET application only


This section shows you how to create a .NET application that generates a temporary SSO token, if necessary, and then uses that token. For a full tutorial of this process, see [Tutorial for SSO using only .NET applications](sso-tutorial-app-only.md).

#### Generate and use an SSO token programmatically


In addition to using the AWS CLI, you can also generate an SSO token programmatically.

To do this, your application creates an [https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TAWSCredentials.html](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TAWSCredentials.html) object for the SSO profile, which loads temporary credentials if any are available. Then, your application must cast the `AWSCredentials` object to an [https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TSSOAWSCredentials.html](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TSSOAWSCredentials.html) object and set some [Options](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TSSOAWSCredentialsOptions.html) properties, including a callback method that is used to prompt the user for sign-in information, if necessary.

This method is shown in the following code snippet.

**Important**  
Your application must reference the following NuGet packages so that SSO resolution can work:  
`AWSSDK.SSO`
`AWSSDK.SSOOIDC`
Failure to reference these packages will result in a *runtime* exception.

```
static AWSCredentials LoadSsoCredentials()
{
    var chain = new CredentialProfileStoreChain();
    if (!chain.TryGetAWSCredentials("my-sso-profile", out var credentials))
        throw new Exception("Failed to find the my-sso-profile profile");

    var ssoCredentials = credentials as SSOAWSCredentials;

    ssoCredentials.Options.ClientName = "Example-SSO-App";
    ssoCredentials.Options.SsoVerificationCallback = args =>
    {
        // Launch a browser window that prompts the SSO user to complete an SSO sign-in.
        // This method is only invoked if the session doesn't already have a valid SSO token.
        // NOTE: Process.Start might not support launching a browser on macOS or Linux. If not,
        //       use an appropriate mechanism on those systems instead.
        Process.Start(new ProcessStartInfo
        {
            FileName = args.VerificationUriComplete,
            UseShellExecute = true
        });
    };

    return ssoCredentials;
}
```

If an appropriate SSO token isn't available, the default browser window is launched and the appropriate sign-in page is opened. For example, if you’re using IAM Identity Center as the **Identity source**, the user sees a sign-in page similar to the following:

![\[AWS IAM Identity Center sign-in page.\]](http://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/images/SSO-login.png)


**Note**  
The text string that you provide for `SSOAWSCredentials.Options.ClientName` can't have spaces. If the string does have spaces, you'll get a *runtime* exception.

[Tutorial for SSO using only .NET applications](sso-tutorial-app-only.md)

### AWS CLI and .NET application


This section shows you how to generate a temporary SSO token by using the AWS CLI, and how to use that token in an application. For a full tutorial of this process, see [Tutorial for SSO using the AWS CLI and .NET applications](sso-tutorial-cli-and-app.md).

#### Generate an SSO token by using the AWS CLI


In addition to generating a temporary SSO token programmatically, you use the AWS CLI to generate the token. The following information shows you how.

After the user creates an SSO-enabled profile as shown in a [previous section](#sso-profiles), they run the `aws sso login` command from the AWS CLI. They must be sure to include the `--profile` parameter with the name of the SSO-enabled profile. This is shown in the following example:

```
aws sso login --profile my-sso-profile
```

If the user wants to generate a new temporary token after the current one expires, they can run the same command again.

#### Use the generated SSO token in a .NET application


The following information shows you how to use a temporary token that has already been generated.

**Important**  
Your application must reference the following NuGet packages so that SSO resolution can work:  
`AWSSDK.SSO`
`AWSSDK.SSOOIDC`
Failure to reference these packages will result in a *runtime* exception.

Your application creates an [https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TAWSCredentials.html](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TAWSCredentials.html) object for the SSO profile, which loads the temporary credentials generated earlier by the AWS CLI. This is similar to the methods shown in [Accessing credentials and profiles in an application](creds-locate.md) and has the following form:

```
static AWSCredentials LoadSsoCredentials()
{
    var chain = new CredentialProfileStoreChain();
    if (!chain.TryGetAWSCredentials("my-sso-profile", out var credentials))
        throw new Exception("Failed to find the my-sso-profile profile");

    return credentials;
}
```

The `AWSCredentials` object is then passed to the constructor for a service client. For example:

```
var S3Client_SSO = new AmazonS3Client(LoadSsoCredentials());
```

**Note**  
Using `AWSCredentials` to load temporary credentials isn't necessary if your application has been built to use the `[default]` profile for SSO. In that case, the application can create AWS service clients without parameters, similar to "`var client = new AmazonS3Client();`".

[Tutorial for SSO using the AWS CLI and .NET applications](sso-tutorial-cli-and-app.md)

## Additional resources


For additional help, see the following resources.
+ [What is IAM Identity Center?](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)
+ [Configuring the AWS CLI to use IAM Identity Center](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html#sso-configure-profile)
+ [Using IAM Identity Center credentials in the AWS Toolkit for Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/sso-credentials.html)

## Tutorials


**Topics**
+ [

## Prerequisites
](#sso-prereq)
+ [

## Setting up an SSO profile
](#sso-profiles)
+ [

## Generating and using SSO tokens
](#sso-generate-use-token-overview)
+ [

## Additional resources
](#sso-resources)
+ [

## Tutorials
](#sso-tutorial-links)
+ [Tutorial: .NET application only](sso-tutorial-app-only.md)
+ [Tutorial: AWS CLI and .NET application](sso-tutorial-cli-and-app.md)

# Tutorial for SSO using only .NET applications
Tutorial: .NET application only

This tutorial shows you how to enable SSO for a basic application and a test SSO user. It configures the application to generate a temporary SSO token programmatically instead of [using the AWS CLI](sso-tutorial-cli-and-app.md).

This tutorial shows you a small portion of SSO functionality in the AWS SDK for .NET. For full details about using IAM Identity Center with the AWS SDK for .NET, see the topic with [background information](sso.md). In that topic, see especially the high-level description for this scenario in the subsection called [.NET application only](sso.md#sso-generate-use-token-app-only-summary).

**Note**  
Several of the steps in this tutorial help you configure services like AWS Organizations and IAM Identity Center. If you've already performed that configuration, or if you're only interested in the code, you can skip to the section with the [example code](#sso-tutorial-app-only-code).

## Prerequisites

+ Configure your development environment if you haven't already done so. This is described in sections like [Install and configure your toolchain](net-dg-dev-env.md) and [Get started](net-dg-config.md).
+ Identify or create at least one AWS account that you can use to test SSO. For the purposes of this tutorial, this is called the *test AWS account* or simply *test account*.
+ Identify an *SSO user* who can test SSO for you. This is a person who will be using SSO and the basic applications that you create. For this tutorial, that person might be you (the developer), or someone else. We also recommend a setup in which the SSO user is working on a computer that is not in your development environment. However, this isn't strictly necessary.
+ The SSO user's computer must have a .NET framework installed that's compatible with the one you used to set up your development environment.

## Set up AWS


This section shows you how to set up various AWS services for this tutorial.

To perform this setup, first sign in to the test AWS account as an administrator. Then, do the following:

### Amazon S3


Go to the [Amazon S3 console](https://console.aws.amazon.com/s3/home) and add some innocuous buckets. Later in this tutorial, the SSO user will retrieve a list of these buckets.

### AWS IAM


Go to the [IAM console](https://console.aws.amazon.com/iam/home#/users) and add a few IAM users. If you give the IAM users permissions, limit the permissions to a few innocuous read-only permissions. Later in this tutorial, the SSO user will retrieve a list of these IAM users.

### AWS Organizations


Go to the [AWS Organizations console](https://console.aws.amazon.com/organizations/) and enable Organizations. For more information, see [Creating an organization](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_create.html) in the [AWS Organizations User Guide](https://docs.aws.amazon.com/organizations/latest/userguide/).

This action adds the test AWS account to the organization as the *management account*. If you have additional test accounts, you can invite them to join the organization, but doing so isn't necessary for this tutorial.

### IAM Identity Center


Go to the [IAM Identity Center console](https://console.aws.amazon.com/singlesignon/) and enable SSO. Perform email verification if necessary. For more information, see [Enable IAM Identity Center](https://docs.aws.amazon.com/singlesignon/latest/userguide/step1.html) in the [IAM Identity Center User Guide](https://docs.aws.amazon.com/singlesignon/latest/userguide/).

Then, perform the following configuration.

#### Configure IAM Identity Center


1. Go to the **Settings** page. Look for the **"access portal URL"** and record the value for later use in the `sso_start_url` setting.

1. In the banner of the AWS Management Console, look for the AWS Region that was set when you enabled SSO. This is the dropdown menu to the left of the AWS account ID. Record the Region code for later use in the `sso_region` setting. This code will be similar to `us-east-1`.

1. Create an SSO user as follows:

   1. Go to the **Users** page.

   1. Choose **Add user** and enter the user's **Username**, **Email address**, **First name**, and **Last name**. Then, choose **Next**.

   1. Choose **Next** on the page for groups, then review the information and choose **Add user**.

1. Create a group as follows:

   1. Go to the **Groups** page.

   1. Choose **Create group** and enter the group's **Group name** and **Description**.

   1. In the **Add users to group** section, select the test SSO user that you created earlier. Then, select **Create group.**

1. Create a permission set as follows:

   1. Go to the **Permission sets** page and choose **Create permission set**.

   1. Under **Permission set type**, select **Custom permission set** and choose **Next**.

   1. Open **Inline policy** and enter the following policy:

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "VisualEditor0",
                  "Effect": "Allow",
                  "Action": [
                      "s3:ListAllMyBuckets",
                      "iam:ListUsers"
                  ],
                  "Resource": "*"
              }
          ]
      }
      ```

------

   1. For this tutorial, enter `SSOReadOnlyRole` as the **Permission set name**. Add a **Description** if you want and then choose **Next**.

   1. Review the information and then choose **Create**.

   1. Record the name of the permission set for later use in the `sso_role_name` setting.

1. Go to the **AWS accounts** page and choose the AWS account that you added to the organization earlier.

1. In the **Overview** section of that page, find the **Account ID** and record it for later use in the `sso_account_id` setting.

1. Choose the **Users and groups** tab and then choose **Assign users or groups**.

1. On the **Assign users and groups** page, choose the **Groups** tab, select the group that you created earlier, and choose **Next**.

1. Select the permission set that you created earlier and choose **Next**, then choose **Submit**. The configuration takes a few moments.

## Create example applications


Create the following applications. They will be run on the SSO user's computer.

### List Amazon S3 buckets


Include NuGet packages `AWSSDK.SSO` and `AWSSDK.SSOOIDC` in addition to `AWSSDK.S3` and `AWSSDK.SecurityToken`.

```
using System;
using System.Threading.Tasks;
using System.Diagnostics;


// NuGet packages: AWSSDK.S3, AWSSDK.SecurityToken, AWSSDK.SSO, AWSSDK.SSOOIDC
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;

namespace SSOExample.S3.Programmatic_login
{
    class Program
    {
        // Requirements:
        // - An SSO profile in the SSO user's shared config file.

        // Class members.
        private static string profile = "my-sso-profile";

        static async Task Main(string[] args)
        {
            // Get SSO credentials from the information in the shared config file.
            var ssoCreds = LoadSsoCredentials(profile);

            // Display the caller's identity.
            var ssoProfileClient = new AmazonSecurityTokenServiceClient(ssoCreds);
            Console.WriteLine($"\nSSO Profile:\n {await ssoProfileClient.GetCallerIdentityArn()}");

            // Display a list of the account's S3 buckets.
            // The S3 client is created using the SSO credentials obtained earlier.
            var s3Client = new AmazonS3Client(ssoCreds);
            Console.WriteLine("\nGetting a list of your buckets...");
            var listResponse = await s3Client.ListBucketsAsync();
            Console.WriteLine($"Number of buckets: {listResponse.Buckets.Count}");
            foreach (S3Bucket b in listResponse.Buckets)
            {
                Console.WriteLine(b.BucketName);
            }
            Console.WriteLine();
        }

        // Method to get SSO credentials from the information in the shared config file.
        static AWSCredentials LoadSsoCredentials(string profile)
        {
            var chain = new CredentialProfileStoreChain();
            if (!chain.TryGetAWSCredentials(profile, out var credentials))
                throw new Exception($"Failed to find the {profile} profile");

            var ssoCredentials = credentials as SSOAWSCredentials;

            ssoCredentials.Options.ClientName = "Example-SSO-App";
            ssoCredentials.Options.SsoVerificationCallback = args =>
            {
                // Launch a browser window that prompts the SSO user to complete an SSO login.
                //  This method is only invoked if the session doesn't already have a valid SSO token.
                // NOTE: Process.Start might not support launching a browser on macOS or Linux. If not,
                //       use an appropriate mechanism on those systems instead.
                Process.Start(new ProcessStartInfo
                {
                    FileName = args.VerificationUriComplete,
                    UseShellExecute = true
                });
            };

            return ssoCredentials;
        }

    }

    // Class to read the caller's identity.
    public static class Extensions
    {
        public static async Task<string> GetCallerIdentityArn(this IAmazonSecurityTokenService stsClient)
        {
            var response = await stsClient.GetCallerIdentityAsync(new GetCallerIdentityRequest());
            return response.Arn;
        }
    }
}
```

### List IAM users


Include NuGet packages `AWSSDK.SSO` and `AWSSDK.SSOOIDC` in addition to `AWSSDK.IdentityManagement` and `AWSSDK.SecurityToken`.

```
using System;
using System.Threading.Tasks;
using System.Diagnostics;


// NuGet packages: AWSSDK.IdentityManagement, AWSSDK.SecurityToken, AWSSDK.SSO, AWSSDK.SSOOIDC
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;

namespace SSOExample.IAM.Programmatic_login
{
    class Program
    {
        // Requirements:
        // - An SSO profile in the SSO user's shared config file.

        // Class members.
        private static string profile = "my-sso-profile";

        static async Task Main(string[] args)
        {
            // Get SSO credentials from the information in the shared config file.
            var ssoCreds = LoadSsoCredentials(profile);

            // Display the caller's identity.
            var ssoProfileClient = new AmazonSecurityTokenServiceClient(ssoCreds);
            Console.WriteLine($"\nSSO Profile:\n {await ssoProfileClient.GetCallerIdentityArn()}");

            // Display a list of the account's IAM users.
            // The IAM client is created using the SSO credentials obtained earlier.
            var iamClient = new AmazonIdentityManagementServiceClient(ssoCreds);
            Console.WriteLine("\nGetting a list of IAM users...");
            var listResponse = await iamClient.ListUsersAsync();
            Console.WriteLine($"Number of IAM users: {listResponse.Users.Count}");
            foreach (User u in listResponse.Users)
            {
                Console.WriteLine(u.UserName);
            }
            Console.WriteLine();
        }

        // Method to get SSO credentials from the information in the shared config file.
        static AWSCredentials LoadSsoCredentials(string profile)
        {
            var chain = new CredentialProfileStoreChain();
            if (!chain.TryGetAWSCredentials(profile, out var credentials))
                throw new Exception($"Failed to find the {profile} profile");

            var ssoCredentials = credentials as SSOAWSCredentials;

            ssoCredentials.Options.ClientName = "Example-SSO-App";
            ssoCredentials.Options.SsoVerificationCallback = args =>
            {
                // Launch a browser window that prompts the SSO user to complete an SSO login.
                //  This method is only invoked if the session doesn't already have a valid SSO token.
                // NOTE: Process.Start might not support launching a browser on macOS or Linux. If not,
                //       use an appropriate mechanism on those systems instead.
                Process.Start(new ProcessStartInfo
                {
                    FileName = args.VerificationUriComplete,
                    UseShellExecute = true
                });
            };

            return ssoCredentials;
        }

    }

    // Class to read the caller's identity.
    public static class Extensions
    {
        public static async Task<string> GetCallerIdentityArn(this IAmazonSecurityTokenService stsClient)
        {
            var response = await stsClient.GetCallerIdentityAsync(new GetCallerIdentityRequest());
            return response.Arn;
        }
    }
}
```

In addition to displaying lists of Amazon S3 buckets and IAM users, these applications display the user identity ARN for the SSO-enabled profile, which is `my-sso-profile` in this tutorial.

These applications perform SSO sign-in tasks by providing a callback method in the [Options](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TSSOAWSCredentialsOptions.html) property of an [SSOAWSCredentials](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TSSOAWSCredentials.html) object.

## Instruct SSO user


Ask the SSO user to check their email and accept the SSO invitation. They are prompted to set a password. The message might take a few minutes to arrive in the SSO user's inbox.

Give the SSO user the applications that you created earlier.

Then, have the SSO user do the following:

1. If the folder that contains the shared AWS `config` file doesn't exist, create it. If the folder does exist and has a subfolder called `.sso`, delete that subfolder.

   The location of this folder is typically `%USERPROFILE%\.aws` in Windows and `~/.aws` in Linux and macOS.

1. Create a shared AWS `config` file in that folder, if necessary, and add a profile to it as follows:

   ```
   [default]
   region = <default Region>
   
   [profile my-sso-profile]
   sso_start_url = <user portal URL recorded earlier>
   sso_region = <Region code recorded earlier>
   sso_account_id = <account ID recorded earlier>
   sso_role_name = SSOReadOnlyRole
   ```

1. Run the Amazon S3 application.

1. In the resulting web sign-in page, sign in. Use the user name from the invitation message and the password that was created in response to the message.

1. When sign-in is complete, the application displays the list of S3 buckets.

1. Run the IAM application. The application displays the list of IAM users. This is true even though a second sign-in wasn't performed. The IAM application uses the temporary token that was created earlier.

## Cleanup


If you don't want to keep the resources that you created during this tutorial, clean them up. These might be AWS resources or resources in your development environment such as files and folders.

# Tutorial for SSO using the AWS CLI and .NET applications
Tutorial: AWS CLI and .NET application

This tutorial shows you how to enable SSO for a basic .NET application and a test SSO user. It uses the AWS CLI to generate a temporary SSO token instead of [generating it programmatically](sso-tutorial-app-only.md).

This tutorial shows you a small portion of SSO functionality in the AWS SDK for .NET. For full details about using IAM Identity Center with the AWS SDK for .NET, see the topic with [background information](sso.md). In that topic, see especially the high-level description for this scenario in the subsection called [AWS CLI and .NET application](sso.md#sso-generate-use-token-cli-and-app-summary).

**Note**  
Several of the steps in this tutorial help you configure services like AWS Organizations and IAM Identity Center. If you've already performed those configurations, or if you're only interested in the code, you can skip to the section with the [example code](#sso-tutorial-cli-and-app-code).

## Prerequisites

+ Configure your development environment if you haven't already done so. This is described in sections like [Install and configure your toolchain](net-dg-dev-env.md) and [Get started](net-dg-config.md).
+ Identify or create at least one AWS account that you can use to test SSO. For the purposes of this tutorial, this is called the *test AWS account* or simply *test account*.
+ Identify an *SSO user* who can test SSO for you. This is a person who will be using SSO and the basic applications that you create. For this tutorial, that person might be you (the developer), or someone else. We also recommend a setup in which the SSO user is working on a computer that is not in your development environment. However, this isn't strictly necessary.
+ The SSO user's computer must have a .NET framework installed that's compatible with the one you used to set up your development environment.
+ Be sure that the AWS CLI version 2 is [installed](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) on the SSO user's computer. You can check this by running `aws --version` in a command prompt or terminal.

## Set up AWS


This section shows you how to set up various AWS services for this tutorial.

To perform this setup, first sign in to the test AWS account as an administrator. Then, do the following:

### Amazon S3


Go to the [Amazon S3 console](https://console.aws.amazon.com/s3/home) and add some innocuous buckets. Later in this tutorial, the SSO user will retrieve a list of these buckets.

### AWS IAM


Go to the [IAM console](https://console.aws.amazon.com/iam/home#/users) and add a few IAM users. If you give the IAM users permissions, limit the permissions to a few innocuous read-only permissions. Later in this tutorial, the SSO user will retrieve a list of these IAM users.

### AWS Organizations


Go to the [AWS Organizations console](https://console.aws.amazon.com/organizations/) and enable Organizations. For more information, see [Creating an organization](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_create.html) in the [AWS Organizations User Guide](https://docs.aws.amazon.com/organizations/latest/userguide/).

This action adds the test AWS account to the organization as the *management account*. If you have additional test accounts, you can invite them to join the organization, but doing so isn't necessary for this tutorial.

### IAM Identity Center


Go to the [IAM Identity Center console](https://console.aws.amazon.com/singlesignon/) and enable SSO. Perform email verification if necessary. For more information, see [Enable IAM Identity Center](https://docs.aws.amazon.com/singlesignon/latest/userguide/step1.html) in the [IAM Identity Center User Guide](https://docs.aws.amazon.com/singlesignon/latest/userguide/).

Then, perform the following configuration.

#### Configure IAM Identity Center


1. Go to the **Settings** page. Look for the **"access portal URL"** and record the value for later use in the `sso_start_url` setting.

1. In the banner of the AWS Management Console, look for the AWS Region that was set when you enabled SSO. This is the dropdown menu to the left of the AWS account ID. Record the Region code for later use in the `sso_region` setting. This code will be similar to `us-east-1`.

1. Create an SSO user as follows:

   1. Go to the **Users** page.

   1. Choose **Add user** and enter the user's **Username**, **Email address**, **First name**, and **Last name**. Then, choose **Next**.

   1. Choose **Next** on the page for groups, then review the information and choose **Add user**.

1. Create a group as follows:

   1. Go to the **Groups** page.

   1. Choose **Create group** and enter the group's **Group name** and **Description**.

   1. In the **Add users to group** section, select the test SSO user that you created earlier. Then, select **Create group.**

1. Create a permission set as follows:

   1. Go to the **Permission sets** page and choose **Create permission set**.

   1. Under **Permission set type**, select **Custom permission set** and choose **Next**.

   1. Open **Inline policy** and enter the following policy:

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "VisualEditor0",
                  "Effect": "Allow",
                  "Action": [
                      "s3:ListAllMyBuckets",
                      "iam:ListUsers"
                  ],
                  "Resource": "*"
              }
          ]
      }
      ```

------

   1. For this tutorial, enter `SSOReadOnlyRole` as the **Permission set name**. Add a **Description** if you want and then choose **Next**.

   1. Review the information and then choose **Create**.

   1. Record the name of the permission set for later use in the `sso_role_name` setting.

1. Go to the **AWS accounts** page and choose the AWS account that you added to the organization earlier.

1. In the **Overview** section of that page, find the **Account ID** and record it for later use in the `sso_account_id` setting.

1. Choose the **Users and groups** tab and then choose **Assign users or groups**.

1. On the **Assign users and groups** page, choose the **Groups** tab, select the group that you created earlier, and choose **Next**.

1. Select the permission set that you created earlier and choose **Next**, then choose **Submit**. The configuration takes a few moments.

## Create example applications


Create the following applications. They will be run on the SSO user's computer.

### List Amazon S3 buckets


Include NuGet packages `AWSSDK.SSO` and `AWSSDK.SSOOIDC` in addition to `AWSSDK.S3` and `AWSSDK.SecurityToken`.

```
using System;
using System.Threading.Tasks;

// NuGet packages: AWSSDK.S3, AWSSDK.SecurityToken, AWSSDK.SSO, AWSSDK.SSOOIDC
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;

namespace SSOExample.S3.CLI_login
{
    class Program
    {
        // Requirements:
        // - An SSO profile in the SSO user's shared config file.
        // - An active SSO Token.
        //    If an active SSO token isn't available, the SSO user should do the following:
        //    In a terminal, the SSO user must call "aws sso login --profile my-sso-profile".

        // Class members.
        private static string profile = "my-sso-profile";
        static async Task Main(string[] args)
        {
            // Get SSO credentials from the information in the shared config file.
            var ssoCreds = LoadSsoCredentials(profile);

            // Display the caller's identity.
            var ssoProfileClient = new AmazonSecurityTokenServiceClient(ssoCreds);
            Console.WriteLine($"\nSSO Profile:\n {await ssoProfileClient.GetCallerIdentityArn()}");

            // Display a list of the account's S3 buckets.
            // The S3 client is created using the SSO credentials obtained earlier.
            var s3Client = new AmazonS3Client(ssoCreds);
            Console.WriteLine("\nGetting a list of your buckets...");
            var listResponse = await s3Client.ListBucketsAsync();
            Console.WriteLine($"Number of buckets: {listResponse.Buckets.Count}");
            foreach (S3Bucket b in listResponse.Buckets)
            {
                Console.WriteLine(b.BucketName);
            }
            Console.WriteLine();
        }

        // Method to get SSO credentials from the information in the shared config file.
        static AWSCredentials LoadSsoCredentials(string profile)
        {
            var chain = new CredentialProfileStoreChain();
            if (!chain.TryGetAWSCredentials(profile, out var credentials))
                throw new Exception($"Failed to find the {profile} profile");
            return credentials;
        }
    }

    // Class to read the caller's identity.
    public static class Extensions
    {
        public static async Task<string> GetCallerIdentityArn(this IAmazonSecurityTokenService stsClient)
        {
            var response = await stsClient.GetCallerIdentityAsync(new GetCallerIdentityRequest());
            return response.Arn;
        }
    }
}
```

### List IAM users


Include NuGet packages `AWSSDK.SSO` and `AWSSDK.SSOOIDC` in addition to `AWSSDK.IdentityManagement` and `AWSSDK.SecurityToken`.

```
using System;
using System.Threading.Tasks;

// NuGet packages: AWSSDK.IdentityManagement, AWSSDK.SecurityToken, AWSSDK.SSO, AWSSDK.SSOOIDC
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;

namespace SSOExample.IAM.CLI_login
{
    class Program
    {
        // Requirements:
        // - An SSO profile in the SSO user's shared config file.
        // - An active SSO Token.
        //    If an active SSO token isn't available, the SSO user should do the following:
        //    In a terminal, the SSO user must call "aws sso login --profile my-sso-profile".

        // Class members.
        private static string profile = "my-sso-profile";
        static async Task Main(string[] args)
        {
            // Get SSO credentials from the information in the shared config file.
            var ssoCreds = LoadSsoCredentials(profile);

            // Display the caller's identity.
            var ssoProfileClient = new AmazonSecurityTokenServiceClient(ssoCreds);
            Console.WriteLine($"\nSSO Profile:\n {await ssoProfileClient.GetCallerIdentityArn()}");

            // Display a list of the account's IAM users.
            // The IAM client is created using the SSO credentials obtained earlier.
            var iamClient = new AmazonIdentityManagementServiceClient(ssoCreds);
            Console.WriteLine("\nGetting a list of IAM users...");
            var listResponse = await iamClient.ListUsersAsync();
            Console.WriteLine($"Number of IAM users: {listResponse.Users.Count}");
            foreach (User u in listResponse.Users)
            {
                Console.WriteLine(u.UserName);
            }
            Console.WriteLine();
        }

        // Method to get SSO credentials from the information in the shared config file.
        static AWSCredentials LoadSsoCredentials(string profile)
        {
            var chain = new CredentialProfileStoreChain();
            if (!chain.TryGetAWSCredentials(profile, out var credentials))
                throw new Exception($"Failed to find the {profile} profile");
            return credentials;
        }
    }

    // Class to read the caller's identity.
    public static class Extensions
    {
        public static async Task<string> GetCallerIdentityArn(this IAmazonSecurityTokenService stsClient)
        {
            var response = await stsClient.GetCallerIdentityAsync(new GetCallerIdentityRequest());
            return response.Arn;
        }
    }
}
```

In addition to displaying lists of Amazon S3 buckets and IAM users, these applications display the user identity ARN for the SSO-enabled profile, which is `my-sso-profile` in this tutorial.

## Instruct SSO user


Ask the SSO user to check their email and accept the SSO invitation. They are prompted to set a password. The message might take a few minutes to arrive in the SSO user's inbox.

Give the SSO user the applications that you created earlier.

Then, have the SSO user do the following:

1. If the folder that contains the shared AWS `config` file doesn't exist, create it. If the folder does exist and has a subfolder called `.sso`, delete that subfolder.

   The location of this folder is typically `%USERPROFILE%\.aws` in Windows and `~/.aws` in Linux and macOS.

1. Create a shared AWS `config` file in that folder, if necessary, and add a profile to it as follows:

   ```
   [default]
   region = <default Region>
   
   [profile my-sso-profile]
   sso_start_url = <user portal URL recorded earlier>
   sso_region = <Region code recorded earlier>
   sso_account_id = <account ID recorded earlier>
   sso_role_name = SSOReadOnlyRole
   ```

1. Run the Amazon S3 application. A runtime exception appears.

1. Run the following AWS CLI command:

   ```
   aws sso login --profile my-sso-profile
   ```

1. In the resulting web sign-in page, sign in. Use the user name from the invitation message and the password that was created in response to the message.

1. Run the Amazon S3 application again. The application now displays the list of S3 buckets.

1. Run the IAM application. The application displays the list of IAM users. This is true even though a second sign-in wasn't performed. The IAM application uses the temporary token that was created earlier.

## Cleanup


If you don't want to keep the resources that you created during this tutorial, clean them up. These might be AWS resources or resources in your development environment such as files and folders.