How to handle AWS IAM token to connect with database in ASP.NET Core Web API

Viewed 129

I have MySQL database hosted in AWS and I am using IAM token to connect with it. I am using the following library and code to connect to this database and get tokens.

var token = Amazon.RDS.Util.RDSAuthTokenGenerator.GenerateAuthToken(awsOptions.Credentials, RegionEndpoint.USEast1, creds.Host, (int)creds.Port, creds.UserName);

The token I am getting back has an expiration of 15 minutes but it looks like a sliding expiration, so we keep using a database connection and it keeps adding 15 minutes from the last used token.

Initially, I was calling the library method to get tokens for each database request and it was very slow. It also started giving an error.

I implemented cache for 5 minutes and sliding token expiration is 15 minutes to be safe. It works for 3-4 hours and then looks like the token gets expired even if I continue to use it every 5 seconds. In this case, my application goes down for a maximum of 5 minutes every 3-4 hours.

Sample code for caching

 public IDbConnection GetDbConnection()
    {
        var connectionString = GetConnectionString("connectionName");

        var connection = new MySqlConnection(connectionString);

        try
        {
            connection.Open();
        }
        catch (MySqlException ex)
        {
            // if exception remove cache and get new token
            if (ex.Number == 1045)
            {
                connectionString = GetConnectionString("connectionName", true);
                return new MySqlConnection(connectionString);
            }

            throw;

        }

        connection.Close();

        return connection;
    }

    public string GetConnectionString(string connectionName, bool refreshCache = false)
    {

        if (refreshCache == true)
        {
            var connectionString = GetConnectionStringInternal(connectionName);
            if (this.cache.Get("cacheName") != null)
            {
                this.cache.Remove("cacheName");
            }

            return connectionString;
        }

        var cacheEntry = this.cache.GetOrCreate("cacheName",
           entry =>
           {
               entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);

               return GetConnectionStringInternal(connectionName);
           });
        return cacheEntry;
    }

    private string GetConnectionStringInternal(string connectionName)
    {
        var token = Amazon.RDS.Util.RDSAuthTokenGenerator.GenerateAuthToken(awsOptions.Credentials, RegionEndpoint.USEast1, creds.Host, (int)creds.Port, creds.UserName);
        return $"{connectionString};Uid={creds.UserName};Server={creds.Host}; Port={creds.Port};Password={token};";
    }

What is a way to cache AWS RDS token?

Thank you for your help!

0 Answers
Related