Menu Home

Lets Encrypt SSL Certificates for Azure Web Apps

I have before blogged about my work on a plugin for letsencrypt-win-simple, that eased the installation of Lets Encrypt Certificates on Azure Web Apps.

That project was mostly a trial run to see if it was possible to get it to work, and it is now abandoned. But fear not, I have created a much better solution, an Azure Web App Site Extension that can be used to request and install Lets Encrypt certificates on Azure Web Apps.

I’m not going to go into a lot of details in this blog post on how to use it. I just want to high-light the general process.

To get a SSL certificate for you Azure Web App, for you own custom domain, you need to do three things.

  1. Install the site extension
  2. Create a Azure AD service principal and assign it permission to the resource group that you site belongs to
  3. Request the certificate through a 3 step wizard in the site extension

That all there is to it. When this process have been completed you will be able to use HTTPS on your own domains for free. The certificates will automatically be renewed once they expire (every three months).

You can see a site where I used it here:

This is a great step towards getting HTTPS on more sites, no longer is money the excuse. And it is not too complicated either.

If you are interested in getting started please check my how to install on github.

Categories: Windows Azure

Tagged as:

Simon J.K. Pedersen

8 replies

  1. I just used the extension on my (very simple) sites and Everything worked perfectly except that I got an error message that read something like “‘authority’ Uri should have at least one segment in the path” the first time I posted the extension form. I tried again a few minutes later, and everything worked.

    Great job!

  2. Hi Simon
    I’m struggling to pass the final step of your extension on Azure Websites as it throws an error that it can’t access the public folder. Any idea how to solve it? Below is the error I get when trying to install the certificate:

    Server Error in ‘/letsencrypt’ Application.

    Access to the path ‘site\wwwroot\public\.well-known\acme-challenge’ is denied.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.UnauthorizedAccessException: Access to the path ‘site\wwwroot\public\.well-known\acme-challenge’ is denied.

    ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, and the configured application pool identity on IIS 7.5) that is used if the application is not impersonating. If the application is impersonating via , the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user.

    To grant ASP.NET access to a file, right-click the file in File Explorer, choose “Properties” and select the Security tab. Click “Add” to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.

    Source Error:

    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

    Stack Trace:

    [UnauthorizedAccessException: Access to the path ‘site\wwwroot\public\.well-known\acme-challenge’ is denied.]
    System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +636
    System.IO.Directory.InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, Boolean checkHost) +1349
    System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost) +73
    LetsEncrypt.SiteExtension.Core.CertificateManager.Authorize(Target target) in J:\Projects\letsencrypt-siteextension\LetsEncrypt.SiteExtension.Core\CertificateManager.cs:510
    LetsEncrypt.SiteExtension.Core.CertificateManager.Auto(Target binding) in J:\Projects\letsencrypt-siteextension\LetsEncrypt.SiteExtension.Core\CertificateManager.cs:445
    LetsEncrypt.SiteExtension.Core.CertificateManager.RequestAndInstallInternal(Target target) in J:\Projects\letsencrypt-siteextension\LetsEncrypt.SiteExtension.Core\CertificateManager.cs:248
    LetsEncrypt.SiteExtension.Controllers.HomeController.Install(RequestAndInstallModel model) +705
    lambda_method(Closure , ControllerBase , Object[] ) +139
    System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +209
    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +35
    System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39
    System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +71
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42
    System.Web.Mvc.Async.AsyncInvocationWithFilters.b__3d() +72
    System.Web.Mvc.Async.c__DisplayClass46.b__3f() +386
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42
    System.Web.Mvc.Async.c__DisplayClass2b.b__1c() +30
    System.Web.Mvc.Async.c__DisplayClass21.b__1e(IAsyncResult asyncResult) +186
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
    System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
    System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
    System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
    System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137

    Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1055.0

  3. Hi Simon,

    Thanks for the great site extension. Really appreciate it. I have successfully used it to install a Let’s Encrypt certificate on my azure web app.

    I need to provide my certificate and its private key to a site variation testing platform I use.

    Is it possible to retrieve these at all from the Lets Encrypt certificate site extension?


  4. Great work 🙂 It works great on our development app-services.

    Would it work on Azure App Gateway also? I can see that you have startet a new project on github, called letsencrypt-azure, that should also work on other services in azure. How is the status on that?

Leave a Reply

Your email address will not be published. Required fields are marked *