Connecting on-premise AD to AWS IAM

You can access AWS services using your corporate credentials as defined in your existing Active Directory Federation Services (ADFS) setup. You can also integrate AWS with ADFS to implement single sign-on functionality. When using ADFS with AWS, ADFS acts as the identity provider and AWS acts as a relying party. This recipe includes commands and instructions to create a proxy server to get the temporary credentials from AWS Security Token Service (STS) and a client application that accesses an S3 bucket (using the temporary credentials) from a C# application.

How to do it…

  1. Create a proxy application.

    Create a simple Windows Communication Foundation (WCF) application and add a WCF service class. WCF is a framework for building service-oriented applications. Using WCF, you can send data as asynchronous messages from one service endpoint to another. A service endpoint can be a part of continuously available service hosted by IIS, or it can be a service hosted in an application. In the class, create a Get method that calls STS service for the temporary credentials.

    TemporaryCredentials IProxyService.GetToken()
    {
    //Get username from client request.
    string userName = HttpContext.Current.Request.LogonUserIdentity.Name;
    
    TemporaryCredentials objTemporaryCredentials = new TemporaryCredentials();
    
    //Get the app settings from web.config file.
    NameValueCollection appConfig = ConfigurationManager.AppSettings;
    string accessKeyId = appConfig["accessKeyId"];
    string secretAccessKey = appConfig["secretAccessKey"];
    string bucketName = appConfig["bucketName"];
    
    // Create a client.
    AmazonSecurityTokenServiceConfig config = new AmazonSecurityTokenServiceConfig();
    AmazonSecurityTokenServiceClient client = new AmazonSecurityTokenServiceClient(
    accessKeyId,
    secretAccessKey,
    config);
    
    //Split the user name.
    string[] usernameParts01 = userName.Split('');
    
    // Build the aws username.
    string awsUsernameDomain = usernameParts01[1] + "@" + usernameParts01[0];
    
    // Split username@domain to retrieve the username only.
    string[] usernameParts02 = awsUsernameDomain.Split('@');
    
    //Get username only.
    string awsUsername = usernameParts02[0];
    
    string policy = appConfig["policy_" + awsUsername];
    
    // Replace the [*] values with real values at runtime.
    policy = policy.Replace("[BUCKET-NAME]", bucketName);
    policy = policy.Replace("[USER-NAME]", awsUsername.ToLowerInvariant());
    policy = policy.Replace("'", """);
    
    //Request to get temporary credentials.
    GetFederationTokenRequest request = new GetFederationTokenRequest
    {
    DurationSeconds = 3600 * 8,
    Name = awsUsername,
    Policy = policy
    };
    
    //Get temporary credentials.
    GetFederationTokenResponse objGetFederationTokenResponse = client.GetFederationToken(request);
    
    //Get federation token result.
    GetFederationTokenResult objGetFederationTokenResult = objGetFederationTokenResponse.GetFederationTokenResult;
    
    //Get credentials.
    Credentials objCredentials = objGetFederationTokenResult.Credentials;
    
    //Set user name.
    objTemporaryCredentials.User = userName;
    
    //Set access key id.
    objTemporaryCredentials.AccessKeyId = objCredentials.AccessKeyId;
    
    //Set secret access key.
    objTemporaryCredentials.SecretAccessKey = objCredentials.SecretAccessKey;
    
    //Set expiration.
    objTemporaryCredentials.Expiration = objCredentials.Expiration;
    
    //Set token.
    objTemporaryCredentials.Token = objCredentials.SessionToken;
    
    //Return result.
    return objTemporaryCredentials;
    }
  2. Create a policy in the app settings section with the policy_username key.

    Using policy file specified, the user can list objects in the specified bucket and get objects from the folder with his name:

    {
    'Statement': 
    [
    { 
    'Sid': 'PersonalBucketAccess', 
           'Action': [ 's3:GetObject' ],
           'Effect': 'Allow', 
           'Resource': 'arn:aws:s3:::[BUCKET-NAME]/[USER- NAME]/*' 
    }, 
    { 
           'Sid': 'GeneralBucketList', 
           'Action': [ 's3:ListBucket' ], 
           'Effect': 'Allow', 
    'Resource': 'arn:aws:s3:::[BUCKET-NAME]' 
    }
    ]
    }
  3. Host the WCF service and set the authentication to Windows Authentication for this application on IIS. You will need to add the following binding configuration in your web.config file. The configuration sets the security mode to TransportCredentialOnly.
    <bindings>
    <webHttpBinding>
    <binding name="default">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" proxyCredentialType="Windows" />
      </security>
    </binding>
    </webHttpBinding>
    </bindings>
  4. Create a client application.

    Create a C# console application that accomplishes the following tasks:

    • Call the proxy server and get temporary credentials
    • Get list of object in the specified bucket
    • Get file data from the specified bucket

    If you try to access the folder belonging to a user other than the logged-in user, you will get an access denied message.

    //Web request to call proxy service.
    HttpWebRequest request = 
    (HttpWebRequest)WebRequest.Create(" 
    http://ProxyServiceURL/ProxyService.svc/GetToken ");
    
    request.UseDefaultCredentials = true;
    request.Credentials = 
    System.Net.CredentialCache.DefaultCredentials;
    
    //Get the response.
    HttpWebResponse response = response = (HttpWebResponse)request.GetResponse();
    
    //Check for status code.
    if (response.StatusCode == HttpStatusCode.OK)
                {
    //Get response stream.
    using (StreamReader reader = new 
    StreamReader(response.GetResponseStream()))
                    {
    //Read response.
                        string json = reader.ReadToEnd();
    
    //Initialize DataContractJsonSerializer.
                        DataContractJsonSerializer serializer = 
                        new 
                        DataContractJsonSerializer 
                        (typeof(TemporaryCredentials));
    
        //Get memory stream.
                        MemoryStream ms = new 
                        MemoryStream 
                       (Encoding.Default.GetBytes(json));
    
        //Get deserialized object.
                        TemporaryCredentials 
                        objTemporaryCredentials = 
                        (TemporaryCredentials) 
                        serializer.ReadObject(ms);
    
        //Bucket name.
                        string bucketName = "clientdocs01";
    
        //File name.
                        string fileName = 
                        "administrator/Note.txt";
    
        //Set AWS credentials and token.
                       SessionAWSCredentials 
                       objSessionAWSCredentials = new
                       SessionAWSCredentials(
                       objTemporaryCredentials.AccessKeyId,
                       objTemporaryCredentials.SecretAccessKey,
                       objTemporaryCredentials.Token);
    
        //Create S3 client object to access S3 service.
                       AmazonS3Client objAmazonS3Client = new 
                       AmazonS3Client(objSessionAWSCredentials, 
                       Amazon.RegionEndpoint.APSoutheast1);
    
        //Prepare list object request.
                        ListObjectsRequest 
                        objListObjectsRequest = new 
                        ListObjectsRequest();
    
        //Set bucket name.
                        objListObjectsRequest.BucketName = 
                        bucketName;
    
        //Get response from AWS S3.
                        ListObjectsResponse 
                        objListObjectsResponse = 
                        objAmazonS3Client.ListObjects 
                        (objListObjectsRequest);
    
           //Iterate over S3 objects.
                        for (int i = 0; i < 
                        objListObjectsResponse.S3Objects.Count; 
                         i++)
                        {
           //Display object name.
                            Console.WriteLine("	" + 
                            objListObjectsResponse. 
                            S3Objects[i].Key);
                        }
    
           //Prepare get object request.
                        GetObjectRequest objGetObjectRequest = 
                        new GetObjectRequest();
    
           //Set bucket name.
                        objGetObjectRequest.BucketName = 
                        bucketName;
    
           //Set file name.
                        objGetObjectRequest.Key = fileName;
    
           //Get object data.
                        GetObjectResponse objGetObjectResponse 
                        = objAmazonS3Client.GetObject 
                        (objGetObjectRequest);
    
           //Get response stream.
                        using (StreamReader objStreamReader = 
                        new StreamReader 
                        (objGetObjectResponse.ResponseStream))
                        {
           //Read response.
                            Console.WriteLine("Contents :" + 
                            objStreamReader.ReadToEnd());
                        }
                    }
                }
    

How it works…

AD FS integration is an important organization because their users don't need to use a different set of credentials for AWS access. The proxy application used to get temporary credentials from AWS Security Token Service (STS) should be a domain-joined machine. The proxy server stores the mapping between the user and the policy. To retrieve temporary credentials, the proxy server needs AccessKeyId and SecretAccessKey. We create an IAM user, assign the permissions, and create access keys for the user.

Before creating the sample application, download the .Net SDK using NuGet packager. In Visual Studio's NuGet console, run the following command. After running the command, add the namespace to your project.

Install-Package AWSSDK

The machine running the client application should be a domain-joined machine. In the client application, you call proxy service to get the temporary credentials and access the S3 data from user folder.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset