Category: .NET


Creating Access Policies in Code

by Norm Johanson | on | in .NET | Permalink | Comments |  Share

AWS uses access policies to restrict access to resources. These policies are JSON documents that have statements, actions, resources, and conditions. You could use a JSON parser to create these documents in code, but a better way would be to use the AWS SDK for .NET Policy object found in the Amazon.Auth.AccessControlPolicy namespace. This gives you type safety and is much more readable than writing text to a JSON parser. For example, imagine you are building a system where desktop clients upload user data directly to Amazon S3 instead of uploading to a web server that would do the upload to S3. You don’t want to bundle the credentials to get to S3, so the desktop clients need to get their credentials from a web server. You want the clients to be able to do GET and PUT requests in S3 under their username in a specific bucket.

The following code creates the policy object. For this case, you need only one statement. It has a resource of bucket + username and the GET and PUT actions. As an added security measure, let’s add a condition that locks the GET and PUT request to the IP address of the desktop client.

public Policy GeneratePolicy(string bucket, string username, string ipAddress)
{
    var statement = new Statement(Statement.StatementEffect.Allow);

    // Allow access to the sub folder represented by the username in the bucket
    statement.Resources.Add(ResourceFactory.NewS3ObjectResource(bucket, username + "/*"));

    // Allow Get and Put object requests.
    statement.Actions = new List() 
        { S3ActionIdentifiers.GetObject,  S3ActionIdentifiers.PutObject };

    // Lock the requests coming from the client machine.
    statement.Conditions.Add(ConditionFactory.NewIpAddressCondition(ipAddress));

    var policy = new Policy();
    policy.Statements.Add(statement);

    return policy;
}

Once you have the policy, you can create a federated user, like this:

public Credentials GetFederatedCredentials(Policy policy, string username)
{
    var request = new GetFederationTokenRequest()
    {
        Name = username,
        Policy = policy.ToJson() 
    };

    var stsClient = new AmazonSecurityTokenServiceClient();

    var response = stsClient.GetFederationToken(request);
    return response.GetFederationTokenResult.Credentials;
}

The credentials object contains a temporary access key, a secret key, and a session token that can be sent back to the desktop client. The desktop client can then construct an S3 client, like this:

string accessKeyId, secretAccessKey, sessionToken;
GetCredentialsFromWebServer(out accessKeyId, out secretAccessKey, out sessionToken);

var sessionCredentials = new SessionAWSCredentials(accessKeyId, secretAccessKey, sessionToken);
AmazonS3 s3Client = new AmazonS3Client(sessionCredentials, RegionEndpoint.USWest2);

public void GetCredentialsFromWebServer(out string accessKeyId, out string secretAccessKey, out string sessionToken)
{
    ... Make web request to get temporary restricted credentials. ...
}

Now the desktop client can upload and download data to S3 without the ability to access other user’s data.

Connecting to Amazon EC2 Instances from the AWS Toolkit for Visual Studio

by Norm Johanson | on | in .NET | Permalink | Comments |  Share
I think the feature I use the most in the
AWS Toolkit for Visual Studio is being able to quickly connect to my EC2 instances with Remote Desktop. I use the toolkit to store my private keys encrypted so when I want to remote desktop, all I have to do is confirm I want to use the key pair and click
OK.
 
For example, let’s say I want to remote desktop into my instance. I would navigate to the
EC2 Instances view, right-click my instance, and click
Open Remote Desktop.
 
 
In this case, I have not yet used the private key with the toolkit, so it prompts me to enter my private key. I’m going to leave the
Save Private Key field checked to make it easier to remote desktop in the future, and then I click
OK.
 
 
Now the toolkit starts the Remote Desktop session, and in a few seconds I will be in my Windows instance ready to go. The next time I attempt to connect to this instance or any instance that uses the same key pair, I’ll get a connect box like the one below.
 
 
Since the toolkit has the private key stored in it, I’m no longer prompted to enter my private key. I just need to confirm I want to use this specific key pair to log on, and the toolkit takes care of the rest.
 
Not only can I remote desktop from the
EC2 Instances view, but I can also remote desktop directly from the AWS Elastic Beanstalk
Environment view and the AWS CloudFormation
Stack view by clicking the
Connect to Instance button in the toolbar. If multiple EC2 instances are associated with the environment or stack, I will first be prompted for the specific EC2 instance I want to connect to.
 
I can also use the toolkit to connect to my Linux instances just as easily. In this case, the toolkit will use the Windows SSH client Putty, which I needed to install before attempting to SSH. The toolkit gives me all the same advantages of storing my private key and takes care of converting the private key from its native PEM format to Putty’s PPK format.
 

Logging with the AWS SDK for .NET

by Steve Roberts | on | in .NET | Permalink | Comments |  Share

As we announced previously, the AWS SDK for .NET now supports easily-configurable logging to both log4net and .NET’s built-in System.Diagnostics logging. In this post, we cover how to enable and configure this new functionality, and how you can easily collect performance metrics for the SDK.

Both log4net and System.Diagnostics logging approaches have their own advantages and disadvantages, but we’re not covering those here. Which approach you take depends on your specific needs.

Turning on log4net or System.Diagnostics logging, or even both, is now very simple to do: just add the appropriate XML sections to your application’s config file (app.config or web.config, for example), and you’re done! As long as you are using version 1.5.n or higher of the AWS SDK for .NET, there is no need to change any code or recompile your application. (To use log4net, remember that you must download the necessary binaries from the download site and place those alongside the AWSSDK.dll assembly.)

Configuring Logging

To make logging as easy as possible, we have introduced an application setting key, AWSLogging, that configures logging for the entire SDK. The key can be set to one of the following values:

  • "log4net" – only use log4net
  • "SystemDiagnostics" – log using System.Diagnostics
  • "SystemDiagnostics, log4net" – log to both system
  • "None" – completely disable logging

In this post, we demonstrate configuring this setting and the associated loggers.

Configuring log4net

The simplest approach to logging is to direct the logs to a file on your local system. The following configuration shows how to use log4net and direct all logs to the file located at C:Logssdk-log.txt.

<configSections>
  <section name="log4net" 
           type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>

<log4net>
  <appender name="FileAppender" type="log4net.Appender.FileAppender,log4net">
    <file value="C:Logssdk-log.txt"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern 
             value="%date [%thread] %level %logger - %message%newline"/>
    </layout>
  </appender>

  <logger name="Amazon">
    <level value="INFO"/>
    <appender-ref ref="FileAppender"/>
  </logger>
</log4net>

<appSettings>
  <!-- Configure the SDK to use log4net -->
  <add key="AWSLogging" value="log4net"/>
</appSettings>

If you are considering using log4net logging full-time, use RollingFileAppender instead of FileAppender. Otherwise, your logs may grow too large in size.

System.Diagnostics

You can implement the same kind of local-file logging with System.Diagnostics as well. Here’s a comparable configuration:

<configuration>
  <appSettings>
    <!-- Configure the SDK to use System.Diagnostics -->
    <add key="AWSLogging" value="SystemDiagnostics"/>
  </appSettings>

  <system.diagnostics>
    <trace autoflush="true"/>

    <sources>
      <source name="Amazon">
        <listeners>
          <add name="text" 
               type="System.Diagnostics.TextWriterTraceListener" 
               initializeData="c:Logssdk-log.txt"/>
        </listeners>
      </source>
    </sources>

  </system.diagnostics>
</configuration>

Metrics

The AWS SDK for .NET has recently started logging performance metrics for most service calls. These metrics can also be enabled through a configuration update. This is done using a switch similar to AWSLogging called AWSLogMetrics. This value is a simple boolean field that accepts "true" and "false" as inputs. Here is an example:

<appSettings>
  <!-- Enable SDK metrics logging -->
  <add key="AWSLogMetrics" value="true"/>
  <!-- Logging must be enabled to collect metrics -->
  <add key="AWSLogging" value="log4net,SystemDiagnostics"/>
</appSettings>

When you include this setting in your configuration, the SDK will collect and log performance metrics for every service call. Below is a sample metric log from log4net:

2013-02-24 00:11:59,467 [1] INFO Amazon.DynamoDB.AmazonDynamoDBClient - Request metrics: ServiceName = AmazonDynamoDB; ServiceEndpoint = https://dynamodb.us-east-1.amazonaws.com/; MethodName = ListTablesRequest; AsyncCall = False; StatusCode = OK; AWSRequestID = RRAMEONOVS6EEMP2GVMVDF59DJVV4KQNSO5AEMVJF66Q9ASUAAJG; BytesProcessed = 132; CredentialsRequestTime = 00:00:00.0015676; RequestSigningTime = 00:00:00.0134851; HttpRequestTime = 00:00:00.7279260; ResponseUnmarshallTime = 00:00:00.0057781; ResponseProcessingTime = 00:00:00.1004697; ClientExecuteTime = 00:00:00.8906012; 

As you can see, we identify the .NET client issuing the request, the service, the endpoint, the method, whether this is an asynchronous call, and the response. We also identify timings, including how long the HTTP request took to complete and the total SDK call time. Note that logging must be enabled in order for any metrics to be collected.

Logger Hierarchy

You can use logger hierarchies for both log4net and System.Diagnostics to choose which SDK services will log events. You do this by configuring the loggers based on the namespace of the source. The earlier examples we covered will capture logs for all service calls, as they reference "Amazon", which is the hierarchical parent of all loggers in the SDK. If you were only interested in DynamoDB logs, for instance, you would reference "Amazon.DynamoDB". And since there are multiple logging options and both log4net and System.Diagnostics support multiple listeners/loggers, it’s even possible to configure for different services to be logged to different destinations.

Below, you can see how easy it is to configure log4net to capture Route53 logs and System.Diagnostics to handle only DynamoDB messages.

log4net:

<logger name="Amazon.Route53">
  <level value="INFO"/>
  <appender-ref ref="FileAppender"/>
</logger>

System.Diagnostics:

<source name="Amazon.DynamoDB">
  <listeners>
    <add name="text" 
         type="System.Diagnostics.TextWriterTraceListener" 
         initializeData="c:Logssdk-log.txt"/>
  </listeners>
</source>

Summary

In this post, we covered the available logging approaches present in the AWS SDK for .NET. You learned how to configure logging with both log4net and System.Diagnostics, and how to configure both sets of tools to collect only the data you need. You’ve also seen how simple it is to gather metrics data for the SDK.

As a final note, both log4net and System.Diagnostics provide extensive approaches to logging, though we covered only a small subset of that in this blog post. We recommend checking out the log4net and TraceSource documentation to acquaint yourself with these technologies.

Welcome to the AWS SDKs and Tools .NET blog

by Steve Roberts | on | in .NET | Permalink | Comments |  Share

Welcome to the AWS SDKs and Tools .NET blog. We’re glad to see you here!

  • This blog features information for AWS .NET developers, including:
  • Demonstrations of new features in the AWS SDK for .NET
  • Announcements and demonstrations of new features in the AWS Toolkit for Microsoft Visual Studio and AWS Tools for Windows PowerShell
  • Best practices for using the SDK
  • Important AWS product announcements for .NET developers
  • Lots of code samples

You’ll see content from many of our team members, including developers from the SDKs and Tools team.

We hope you come back often to visit or subscribe to our blog using the RSS feed button at the top of the page. If you’d like us to cover any specific topics, please let us know and we’ll do our best.