title: How to ASP.NET Core 1.0.1 API HTTPS with Kestrel
body: <p>we want to implement an ASP.NET Core API (1.0.1) on an IIS Webserver (as proxy) which is runing on a Kestrel server.
  Clients running agains the API should do this with an Certificate ussied by our company CA.
  The user than should be authenticated by "Active Directory Client Certificate Authentication".</p>
  
  <p>We are developing with Visual Studio 2015 (Update 3) on a developer client (not the web server).</p>
  
  <p>After reading the trying to understand the machanisms I just tried a bit in code.
  Sadly try and error does not helped much :)</p>
  
  <p>Afterwards I tried to find some tutorials on the internet, but most of them are just covering parts of the solution and furthermore most of them are targeting ASP.NET 5.</p>
  
  <p><strong>So whats my question?</strong></p>
  
  <ul>
  <li>Is there any good guide out there for my scenario?</li>
  <li>Is there any guide covering SSL with a real company CA (not just self created Developer CA Certs)</li>
  <li>Is it possible to enable SSL in IIS Express for debugging?</li>
  <li>How can I read a Client certificate in code; GetClientCertificateAsync() ALWAYS is null.</li>
  <li>Do I may have an understanding issue?:</li>
  </ul>
  
  <p>Client --(SSL Cert)--> <a href="https://API" rel="nofollow noreferrer">https://API</a> (IIS --> Kestrel)</p>
  
  <p>Do Kestrel need to use <code>"Microsoft.AspNetCore.Server.Kestrel.Https": "1.0.1"</code> when I just want to authenticate the client cert via AD and read the certificate in my API to get the UPN?</p>
  
  <p><strong>What have i tried?</strong></p>
  
  <p>First I added <code>"Microsoft.AspNetCore.Server.Kestrel.Https": "1.0.1",</code> to the project.json file.</p>
  
  <p>In the Startup.cs file I added the following code into the <code>ConfigureServices</code> function:</p>
  
  <pre><code> services.Configure&lt;KestrelServerOptions&gt;(options =&gt;
          {
              options.ThreadCount = 4;
              options.UseConnectionLogging();
  
              HttpsConnectionFilterOptions https = new HttpsConnectionFilterOptions();
              https.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
              https.ServerCertificate = GetCetificate();
              https.CheckCertificateRevocation = false;
  
              options.UseHttps(https);
          });
  </code></pre>
  
  <p><code>GetCetificate()</code> retreives a certificate from the local store (<strong>I think here I need a real server certificate with private key?</strong>)</p>
  
  <p>I am listening to the following ports:</p>
  
  <p><code>"server.urls": "http://localhost:6000;https://localhost:6001;"</code></p>
  
  <p>I let the default ValuesController untouched for testing.
  When I run the API-Profile (NOT IIS Express) <code>http://localhost:6000/api/values</code> return the json data. When I request <code>https://localhost:6001/api/values</code> I got the following error:</p>
  
  <blockquote>
    <p>fail: Microsoft.AspNetCore.Server.Kestrel[0]
          ConnectionFilter.OnConnection System.AggregateException: One or more errors occurred. (The server mode SSL must use a certificate with
    the associated private key.) ---> System.NotSupportedException: The
    server mode SSL must use a certificate with the associated private
    key.    at
    System.Net.Security.SecureChannel.AcquireServerCredentials(Byte[]&amp;
    thumbPrint)    at
    System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32
    offset, Int32 count, Byte[]&amp; output)    at
    System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32
    offset, Int32 count)    at
    System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32
    count, AsyncProtocolRequest asyncRequest)    at
    System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
    count, AsyncProtocolRequest asyncRequest)    at
    System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
    readBytes, AsyncProtocolRequest asyncRequest)    at
    System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest
    asyncRequest)
    --- End of stack trace from previous location where exception was thrown ---    at
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()    at
    System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult
    lazyResult)    at
    System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult
    result)    at
    System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult
    asyncResult)    at
    System.Threading.Tasks.TaskFactory<code>1.FromAsyncCoreLogic(IAsyncResult
    iar, Func</code>2 endFunction, Action<code>1 endAction, Task</code>1 promise, Boolean
    requiresSynchronization)
    --- End of stack trace from previous location where exception was thrown ---    at
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
    task)    at
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
    task)    at
    Microsoft.AspNetCore.Server.Kestrel.Https.HttpsConnectionFilter.d__3.MoveNext()
    --- End of inner exception stack trace ---
    ---> (Inner Exception #0) System.NotSupportedException: The server mode SSL must use a certificate with the associated private key.    at
    System.Net.Security.SecureChannel.AcquireServerCredentials(Byte[]&amp;
    thumbPrint)    at
    System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32
    offset, Int32 count, Byte[]&amp; output)    at
    System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32
    offset, Int32 count)    at
    System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32
    count, AsyncProtocolRequest asyncRequest)    at
    System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
    count, AsyncProtocolRequest asyncRequest)    at
    System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
    readBytes, AsyncProtocolRequest asyncRequest)    at
    System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest
    asyncRequest)
    --- End of stack trace from previous location where exception was thrown ---    at
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()    at
    System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult
    lazyResult)    at
    System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult
    result)    at
    System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult
    asyncResult)    at
    System.Threading.Tasks.TaskFactory<code>1.FromAsyncCoreLogic(IAsyncResult
    iar, Func</code>2 endFunction, Action<code>1 endAction, Task</code>1 promise, Boolean
    requiresSynchronization)
    --- End of stack trace from previous location where exception was thrown ---    at
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
    task)    at
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
    task)    at
    Microsoft.AspNetCore.Server.Kestrel.Https.HttpsConnectionFilter.d__3.MoveNext()&lt;---</p>
  </blockquote>
  
  <p>Running IIS Express it seems to work (via <a href="http://localhost:31943/" rel="nofollow noreferrer">http://localhost:31943/</a> and <a href="https://localhost:44317/" rel="nofollow noreferrer">https://localhost:44317/</a> configured in the launchSettings.json)
  But nevertheless I still can't get the ClientCertificate.</p>