In the previous sections, you set up the ASP.NET Core MVC project to use DynamoDB as the backing store for the Session middleware. However, the Session middleware encrypts the session cookie it uses to track users with encryption keys that are generated locally and not shared by default. This means that if you have multiple copies of your web application running - on multiple EC2 instances, containers or Lambda functions for example - they cannot decrypt each other’s session cookies. This will break session state unless you configure a load balancer to use “sticky sessions”, which is not always feasible, nor desirable.
Luckily, we can configure ASP.NET Core to use whatever repository we choose to store the encryption keys, so that they can be shared across multiple running instances of an application. You could choose, for instance, to store the keys in a DynamoDB table. However, AWS has a service, called Parameter Store (part of Simple Systems Manager) that can store parameters up to 4K in length, and retrieve them by path. You can optionally choose to encrypt values stored in Parameter Store with AWS Key Management Service (KMS) to keep them secure (recommended for any production environment). For this lab, we’ll just store them as plaintext in order to view them.
Follow the steps below to add an implementation of IXmlRespository that stores cookie encryption keys in AWS Parameter Store.
Note: This is example code for use with this lab, and should not be considered production-ready. There is no error handling, testing, or other features required for production applications.
StoreElement takes in a XElement and stores it as a parameter in Parameter Store, with the name set to "CookieEncryptionKey" plus the friendly name (a GUID) passed in by the middleware. GetAllElements uses the GetParametersByPathAsync method of Parameter Store to get all parameters that begin with, "CookieEncryptionKey", and returns them as a collection of XElement.
using Amazon.SimpleSystemsManagement; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection.Repositories; using Session;
services.AddAWSService<IAmazonSimpleSystemsManagement>(); services.AddSingleton<IXmlRepository, PsXmlRepository>(); var sp = services.BuildServiceProvider(); services.AddDataProtection().AddKeyManagementOptions(o => o.XmlRepository = sp.GetService<IXmlRepository>());
You could not deploy this web application to a web-server farm, or as multiple containers in Amazon ECS or EKS, or add Lambda support to the project and deploy it to Lambda, and the session state would work across the multiple copies. Also, note that the code you
Actually deploying it to those environments is outside the scope of this lab, but feel free to try it out at home!
In this lab, you learned how to use DynamoDB as the backing store for ASP.NET Core’s Session middleware, and optionally, to use Parameter Store to enable using the solution for a distributed web application.
You also tested out your solution running locally on your laptop or PC, and looked at the session item(s) in DynamoDB, and optionally looked the encryption key XML as stored in AWS Parameter Store.