How do I get ASP.Net Core Razor Pages to comply with what letsencrypt.com requires for "handshaking?" I had tried using a solution that works with MVC but the way the Route was done didn't work in Razor Pages.
I started with this excellent tutorial from the Royal Jay site. Adding a Route to the web app is where my solution diverges from a normal MVC application. Being that you have to get a new SSL certificate every 3 months, I made this solution configurable so that changing the key end up being pretty easy.
In my appsettings.json file, I added the following entry for LetsEncrypt:
"LetsEncrypt": {
"Key": "the entire key from your letsencrypt initial session goes here"
}
The entry here is the entire key that you receive back from the letsencrypt-auto executable (it's the second red-underlined section in the Royal Jay tutorial).
In order to pass the configuration property through to the page that will handle the handshake from LetsEncrypt, I created a new interface and small class that will hold the key:
Interface:
using System;
using System.Collections.Generic;
using System.Text;
namespace Main.Interfaces
{
public interface ILetsEncryptKey
{
string GetKey();
}
}
Class:
using Main.Interfaces;
namespace Main.Models
{
public class LetsEncryptKey : ILetsEncryptKey
{
private readonly string _key;
public LetsEncryptKey(string key) => _key = key;
public string GetKey() => _key;
}
}
Then in the startup.cs file, I've added these lines into the ConfigureServices section:
var letsEncryptInitialKey = Configuration["LetsEncrypt:Key"];
services.AddMvc().AddRazorPagesOptions(options =>
{
options.Conventions.AddPageRoute("/LetsEncrypt", $".well-known/acme-challenge/{letsEncryptInitialKey.Split('.')[0]}");
});
services.AddSingleton<ILetsEncryptKey>(l => new LetsEncryptKey(letsEncryptInitialKey));
Now the only thing we have left to do is to create the page that will handle the handshake request and return the response.
LetsEncrypt.cshtml.cs:
using Main.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPages.Pages
{
public class LetsEncryptModel : PageModel
{
private readonly ILetsEncryptKey _letsEncryptKey;
public LetsEncryptModel(ILetsEncryptKey letsEncryptKey)
{
_letsEncryptKey = letsEncryptKey;
}
public ContentResult OnGet()
{
var result = new ContentResult
{
ContentType = "text/plain",
Content = _letsEncryptKey.GetKey()
};
return result;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With