1

We are using Identity Server4 with EntityFrameworkCore and we have deployed our .NET Core application as a lambda function using aws toolkit ("https://aws.amazon.com/blogs/developer/preview-of-the-aws-toolkit-for-visual-studio-2017/"). So how we can replace AddDeveloperSigningCredential on aws serverless lambda environment?

Here is our ConfigurationServerices method:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IConfiguration>(Configuration);

        string connectionString = Configuration.GetConnectionString("IdentityServer");

        var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

        services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            // this adds the config data from DB (clients, resources)
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = builder =>
                builder.UseSqlServer(connectionString,
                sql => sql.MigrationsAssembly(migrationsAssembly));
            }) // this adds the operational data from DB (codes, tokens, consents)
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = builder =>
                builder.UseSqlServer(connectionString,
            sql => sql.MigrationsAssembly(migrationsAssembly));

                // this enables automatic token cleanup. this is optional.
                // options.EnableTokenCleanup = true;
                // options.TokenCleanupInterval = 30;
            });

        // Add S3 to the ASP.NET Core dependency injection framework.
        services.AddAWSService<Amazon.S3.IAmazonS3>();
    }
Rakesh Kumar
  • 2,701
  • 9
  • 38
  • 66

1 Answers1

4

This is some example code that loads certs from the certificate store. If this is unavailable to you then you just need to serialise and persist the certificate(s) you need some other way but that ultimately yields a valid X509Certificate2 instance that you can pass into X509SecurityKey.

private static void ConfigureSigningCerts(IServiceCollection services)
{
    var keys = new List<SecurityKey>();

    var name = "MyCertName";

    //The one that expires last at the top
    var certs = X509.LocalMachine.My.SubjectDistinguishedName.Find("CN=" + name, false)
        .Where(o => DateTime.UtcNow >= o.NotBefore)
        .OrderByDescending(o => o.NotAfter);

    if (!certs.Any()) throw new Exception("No valid certificates could be found.");

    //Get first (in desc order of expiry) th
    var signingCert = certs.FirstOrDefault();

    if (signingCert == null) throw new InvalidOperationException("No valid signing certificate could be found.");

    var signingCredential = new SigningCredentials(new X509SecurityKey(signingCert), "RS256");
    services.AddSingleton<ISigningCredentialStore>(new DefaultSigningCredentialsStore(signingCredential));

    foreach (var cert in certs)
    {
        var validationCredential = new SigningCredentials(new X509SecurityKey(cert), "RS256");
        keys.Add(validationCredential.Key);
    }

    services.AddSingleton<IValidationKeysStore>(new DefaultValidationKeysStore(keys));
}

The constructor for X509Certificate2 can take a raw byte[] or a file path so you've got plenty of options when it comes to packaging and distributing the signing/validation certs.

To create a self signed certificate on windows you can use the command:

makecert -r -pe -n "CN=MyCertName" -b 01/01/2015 -e 01/01/2039 -eku 1.3.6.1.5.5.7.3.3 -sky signature -a sha256 -len 2048 mycert.cer

That creates a certificate named MyCertName in a file called mycert.cer.

Full docs for the tool here: https://msdn.microsoft.com/en-us/library/bfsktky3(VS.100).aspx

mackie
  • 4,996
  • 1
  • 17
  • 17
  • thanks @mackie. If we creates self signed certificate on windows, can these certificates will be available on aws environment, after deploy the lambda? – Rakesh Kumar Feb 15 '18 at 17:18
  • I'm not familiar with the specifics of AWS Lambdas but provided you can bundle the certificate with the service somehow (as a file or embedded resource) then I can't imagine it being a problem. – mackie Feb 15 '18 at 18:51
  • Can we use certificates that generated from code instead of loading from file. As described here("https://stackoverflow.com/questions/2315257/how-to-create-a-completely-new-x509certificate2-in-net")? – Rakesh Kumar Feb 16 '18 at 08:20
  • @RakeshKumar I'm assuming with AWS Lambdas you could have any number of processes in play and all of them must use the same cert for signing and validation. However you choose to store/generate them it must result in all processes having the same cert at any given moment – mackie Feb 16 '18 at 10:05
  • when i tried to load cert from code, i used this example("https://stackoverflow.com/questions/2315257/how-to-create-a-completely-new-x509certificate2-in-net"), but i got the run time error "Private key is missing". – Rakesh Kumar Feb 16 '18 at 10:10
  • You need to ensure that the file contains the private key and that it's flagged as exportable – mackie Feb 16 '18 at 10:22
  • i have created identityserver.cer file, but don't how we can load it from solution folder. i copied this file into my solution. – Rakesh Kumar Feb 16 '18 at 11:19
  • Hi @mackie can we create the same certificates(X509Certificate2) on aws environment? – Rakesh Kumar Feb 19 '18 at 04:35
  • Hi @mackie, following statements always returns null – Rakesh Kumar Mar 01 '18 at 11:04
  • var certs = X509.LocalMachine.My.SubjectDistinguishedName.Find("CN=" + name, false) .Where(o => DateTime.UtcNow >= o.NotBefore) .OrderByDescending(o => o.NotAfter); – Rakesh Kumar Mar 01 '18 at 11:04
  • Is there any particular location for x.509 certificates?, i have created self signed certificates from IIS manager – Rakesh Kumar Mar 01 '18 at 11:05
  • It's just an example, you can construct the X509Certificate2 instance any way you like. – mackie Mar 01 '18 at 11:49
  • Okey, actually i have added cert file into my solution, and i want to load certificate from there,because with this can add this as embeded resource can i do this? – Rakesh Kumar Mar 01 '18 at 11:51
  • The class supports taking a raw byte[] in the constructor so loading it from an embedded resource would be trivial, yes. – mackie Mar 01 '18 at 12:10