static void


SSL/TLS (https) is increasingly required for security (e.g. it's mandatory for OAuth2).

SSL (Secure Sockets Layer) has been replaced with TLS (transport layer security). Most people still refer to "SSL" even though they mean TLS.
SSL 3.0 (from 1996) is insecure. Most servers and clients (and IE 7+) use TLS 1.1 or later.
"POODLE" hacks work by downgrading from TLS to insecure SSL. If you don't support IE6, the server can disable SSL.


MVC has a [RequireHttps] attribute, which automatically redirects GET requests from http:// to https://. (Not POSTS, which would invoke dreaded "do you want to re-submit" dialogs).

WebAPI doesn't have RequireHttps, so here's a simple implementation:

using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace Mvc5Auth.Infrastructure
    public class WebApiRequireHttpsAttribute : AuthorizationFilterAttribute
        public override void OnAuthorization(HttpActionContext actionContext)
            var request = actionContext.Request;
            if (request.RequestUri.Scheme == Uri.UriSchemeHttps) return;
            //it's http
            HttpResponseMessage response;
            if (!request.Method.Equals(HttpMethod.Get))
                //post etc
                response = request.CreateResponse(HttpStatusCode.NotFound);
                response.ReasonPhrase = "Must use https";
            else //GET
                //create a copy of the uri with https
                var uri = new UriBuilder(request.RequestUri) { Scheme = Uri.UriSchemeHttps, Port = 443 };
                //build a redirect with the header location and helpful html
                response = request.CreateResponse(HttpStatusCode.Redirect);
                response.Headers.Location = uri.Uri;
                var body = string.Format("<p>Resource available at <a href=\"{0}\">{0}</a>.</p>",
                response.Content = new StringContent(body, Encoding.UTF8, "text/html");
            actionContext.Response = response;

Either use it directly on the controller/method with [WebApiRequireHttps] or apply it in App_Start/WebApiConfig (with a little config switch for local debugging)

if (string.Equals(ConfigurationManager.AppSettings["RequireHttps"], "true", StringComparison.OrdinalIgnoreCase))
    config.Filters.Add(new WebApiRequireHttpsAttribute());

SSL from Certificate Authority

Azure has a good explanation.

Local SSL certificates


For development, you can create a certificate with IIS (IIS section, Server certificates icon, actions "Create Self-Signed Certificate", which puts it in the Personal certificates) or use makecert.

Certificates mmc

Open the Certificates mmc (MMC/ File - Add/Remove Snap-In / pick "Certificates" and "Add" / "Computer Account" / "Local Computer"

The certificate store you need is "Trusted Root Certification Authorities"


Makecert is available using the Visual Studio command prompt (Common7\Tools\VsDevCmd.bat), usually in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin

makecert.exe generates an X509 (.cer) certificate and a private key file (.pvk).

This version (from the Pluralsight course WebAPi2 Security) creates a "certification authority" type cert and converts the pvk and cert files to a more portable pfx. NB dates are mm/dd/yyyy

makecert.exe -r -n "CN=DevRoot" -pe -sv DevRoot.pvk -a sha1 -len 2048 -b 01/31/2010 -e 01/31/2030 -cy authority DevRoot.cer
pvk2pfx.exe -pvk DevRoot.pvk -spc DevRoot.cer -pfx DevRoot.pfx

Import the .cer into Trusted Root Certification Authorities using MMC (NB: just the public key)

Then make an SSL certificate (the obscure -eku OID) using the root certificate.

makecert.exe -iv DevRoot.pvk -ic DevRoot.cer -n "CN=%1" -pe -sv %1.pvk -a sha1 -len 2048 -b 01/31/2010 -e 01/31/2020 -sky exchange %1.cer -eku
pvk2pfx.exe -pvk %1.pvk -spc %1.cer -pfx %1.pfx

Import the .pfx (NB: NOT .cer as you need the private key) into Personal using MMC. Because it was signed with the Trusted Root certificate, the chain is trusted.

In IIS manager, go to Edit Site/Bindings and add an https binding with the SSL certificate.

If you add a new site, ensure IIS_IUSERS has access to the site folder, and add the binding, host name and (in IIS8/Windows Server 2012) Require Server Name Indication (allows multiple host names to use the same server/port)

Finally, in System32/drivers/etc edit hosts to add the alias to the

You can also create client SSL certificates, if you can distribute them and configure IIS to accept client certificates (system.webServer/security/access sslFlags="Ssl, SslNegotiateCert" )


OpenSSL includes a set of command lines tools for converting different file formats.

If you update a certificate, you'll get a .crt and .p7b (without private keys). To create a .pfx, you can use OpenSSL.

To extract the private key from original .pfx if you don't have the private key (normally a .key or .pem extension, internally it's .pem)

openssl pkcs12 -in certname.pfx -nocerts -out key.pem -nodes

To create a .pfx from a private key and a .crt/.cer file:

openssl pkcs12 -export -out certname.pfx -in certname.crt -inkey key.pem