Home > Mobile >  Can't move from calling TLS authenticated Web API from console application to ASP.NET MVC IIS h
Can't move from calling TLS authenticated Web API from console application to ASP.NET MVC IIS h

Time:04-13

I've followed a tutorial on how to create a TLS secured Web API using OWIN and Katana. Everything works fine when I access the Web API using a console application as the client.

But, what I'd like to do is access the API in another ASP.NET MVC site hosted in IIS. When I move the code into a basic controller I get the error

The request was aborted: Could not create SSL/TLS secure channel

I've looked at some other posts that discuss configuring System.Net.ServicePointManager.SecurityProtocol so I've tried that but it doesn't seem to change anything.

I have both sites hosted in IIS using Windows Server 2012 R2 and targeting .NET 4.6.

Code that works in a console application using a client cert but installed under LocalMachine:

static void Main(string[] args)
{
    var handler = new WebRequestHandler();

    handler.ClientCertificates.Add(X509.LocalMachine.My.SubjectDistinguishedName.Find("CN=client").First());

    var client = new HttpClient(handler)
        {
            BaseAddress = new Uri("https://admin.web/api/")
        };

    var response = client.GetAsync("identity").Result;
    response.EnsureSuccessStatusCode();

    var content = response.Content.ReadAsStringAsync().Result;
    Console.WriteLine(JArray.Parse(content));
}

Code that is failing in basic controller when moved into an ASP.NET MVC site:

using System.Web.Mvc;
using System.Net.Http;
using System;
using Thinktecture.IdentityModel;
using System.Linq;
using System.Net;

namespace DataClientWeb.Controllers
{
    public class DefaultController : Controller
    {
        // GET: Default
        public ActionResult Index()
        {
            System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            var handler = new WebRequestHandler();

            handler.ClientCertificates.Add(
                X509.LocalMachine.My.SubjectDistinguishedName.Find("CN=client").First());

            var client = new HttpClient(handler)
            {
                BaseAddress = new Uri("https://admin.web/api/")
            };

            var response = client.GetAsync("identity").Result;
            response.EnsureSuccessStatusCode();

            return View();
        }
    }  
}

I haven't secured web applications using client certificates for authentication before so it's possible I'm just missing something simple here. Any pointers are appreciated.

CodePudding user response:

Web applications in IIS run under application pool identity account which doesn't have permissions to access private keys stored in local machine store. You should explicitly grant private key read permissions to app pool identity account.

In addition, the way how you manage HttpClient instance is flawed, because it may cause memory leak. See HttpClient class' remarks for more details.

  • Related