Disable SSL client certificates on *some* WebAPI controllers?


Deep Space 101

Edit for future readers : Unfortunately, the bounty awarded answer doesn't work;there's nothing I can do about it right now. But please read my own answer below (by testing) - confirmed to work with minimal code changes

We have an Azure cloud service (WebRole) entirely in ASP.NET WebAPI 2.2 (no MVC, front end is Angular). Some of our controllers/REST endpoints communicate with 3rd party cloud services over SSL (client certificate authentication/mutual authentication), the rest of the controllers/endpoints also communicate over SSL with the HTML5/AngularJS frontend (but more traditional servers Authentication) SSL). We don't have any non-SSL endpoints. We have enabled client-side SSL via the following cloud service launch tasks:

IF NOT DEFINED APPCMD SET APPCMD=%SystemRoot%\system32\inetsrv\AppCmd.exe
%APPCMD% unlock config /section:system.webServer/security/access

Problem: The setting is site-wide, so even if the user hits the homepage (eg https://domain.com , which returns angularJS's index.html), their browser will ask them for a client-side SSL certificate. (The following figure)

if there is a way

  1. Restrict client-side SSL certificate requests to only WebAPI controllers that communicate with 3rd party cloud services?

or

  1. Skip client side SSL authentication for a frontend that supports webapi controllers?

Our server's web.config is complex, but the relevant snippet is as follows:

<system.webServer>
  <security>
    <access sslFlags="SslNegotiateCert" />
  </security>
</system.webServer>

Screenshot of the client side hitting the regular WebAPI endpoint but still trying to do client side SSL authentication (happening in any browser, Chrome, Firefox or IE)enter image description here

Deep Space 101

Unfortunately, the answer of cleftheris, who was awarded the bounty, didn't work. It tries to work too late in the HTTP server pipeline/processing to get the client certificate, but this post gave me some ideas.

The solution is based on web.configthis requirement for special handling of "directories" (also for virtual folders or WebAPI routes).

Here is the required logic:

https://www.server.com/acmeapi/ ** => SSL with client certificate

https://www.server.com/ ** => SSL

This is the corresponding configuration

<configuration>
  ...
  <system.webServer>
    <!-- This is for the rest of the site -->
    <security>
      <access sslFlags="Ssl" />
    </security>
  </system.webServer>

  <!--This is for the 3rd party API endpoint-->
  <location path="acmeapi">
    <system.webServer>
      <security>
        <access sslFlags="SslNegotiateCert"/>
      </security>
    </system.webServer>
  </location>
...
</configuration>

bonus points

The above will set the SSL handshake accordingly. Now, you still need to check the client SSL certificate in your code (if it's what you expect). Do this as follows

Controller code:

[RoutePrefix("acmeapi")]
[SslClientCertActionFilter] // <== key part!
public class AcmeProviderController : ApiController
{
    [HttpGet]
    [Route("{userId}")]
    public async Task<OutputDto> GetInfo(Guid userId)
    {
        // do work ...
    }
}

Below are the actual properties that perform SSL client authentication. Can be used to decorate an entire controller or just a specific method.

public class SslClientCertActionFilterAttribute : ActionFilterAttribute
{
    public List<string> AllowedThumbprints = new List<string>()
    {
        // Replace with the thumbprints the 3rd party
        // server will be presenting. You can make checks
        // more elaborate but always have thumbprint checking ...
        "0011223344556677889900112233445566778899",
        "1122334455667788990011223344556677889900" 
    };

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var request = actionContext.Request;

        if (!AuthorizeRequest(request))
        {
            throw new HttpResponseException(HttpStatusCode.Forbidden);
        }
    }

    private bool AuthorizeRequest(HttpRequestMessage request)
    {
        if (request==null)
            throw new ArgumentNullException("request");

        var clientCertificate = request.GetClientCertificate();

        if (clientCertificate == null || AllowedThumbprints == null || AllowedThumbprints.Count < 1)
        {
            return false;
        }

        foreach (var thumbprint in AllowedThumbprints)
        {
            if (clientCertificate.Thumbprint != null && clientCertificate.Thumbprint.Equals(thumbprint, StringComparison.InvariantCultureIgnoreCase))
            {
                return true;
            }
        }
        return false;
    }
}

Related


Disable SSL client certificates on *some* WebAPI controllers?

Deep Space 101 Edit for future readers : Unfortunately, the bounty awarded answer doesn't work;there's nothing I can do about it right now. But please read my own answer below (by testing) - confirmed to work with minimal code changes We have an Azure cloud se

Disable SSL client certificates on *some* WebAPI controllers?

Deep Space 101 Edit for future readers : Unfortunately, the bounty awarded answer doesn't work;there's nothing I can do about it right now. But please read my own answer below (by testing) - confirmed to work with minimal code changes We have an Azure cloud se

Disable SSL client certificates on *some* WebAPI controllers?

Deep Space 101 Edit for future readers : Unfortunately, the bounty awarded answer doesn't work;there's nothing I can do about it right now. But please read my own answer below (by testing) - confirmed to work with minimal code changes We have an Azure cloud se

Disable SSL client certificates on *some* WebAPI controllers?

Deep Space 101 Edit for future readers : Unfortunately, the bounty awarded answer doesn't work;there's nothing I can do about it right now. But please read my own answer below (by testing) - confirmed to work with minimal code changes We have an Azure cloud se

Why disable DNSSEC for SSL certificates?

Do not I want to know one thing about DNSSEC. If I have a domain that I want to get an SSL certificate for, why would they want me to disable DNSSEC in a service that uses Let's Encrypt to issue a certificate for the domain name? I've seen several help sites w

Disable client SSL certificate

Vico I have generated a client key certificate on a self signed secure Mosquittoserver . I have copied the CA with the client key and the client certificate into the client machine. Client subscription works fine: mosquitto_sub -h 192.168.1.8 -t sensor --cafil

Some clients accept SSL certificates; others reject

Paul Draper Some HTTP clients accept this certificate, while others do not. what is the difference? Java rejects it. ((javax.net.ssl.HttpsURLConnection)new java.net.URL("https://www.lucidpress.com") .openConnection()) .getInputStream() javax.net.ssl.S

Some clients accept SSL certificates; others reject

Paul Draper Some HTTP clients accept this certificate, while others do not. what is the difference? Java rejects it. ((javax.net.ssl.HttpsURLConnection)new java.net.URL("https://www.lucidpress.com") .openConnection()) .getInputStream() javax.net.ssl.S

Some SSL certificates in chromium don't work

Benjamin I don't know what's going on, or how to fix this. When I browse to sites like Amazon or Bandcamp, I find one of those bugs in Your connection is not privatechrome . Strangely, when I switch to using FireFox, I can load those sites just fine (and accep

Some clients accept SSL certificates; others reject

Paul Draper Some HTTP clients accept this certificate, while others do not. what is the difference? Java rejects it. ((javax.net.ssl.HttpsURLConnection)new java.net.URL("https://www.lucidpress.com") .openConnection()) .getInputStream() javax.net.ssl.S

Some clients accept SSL certificates; others reject

Paul Draper Some HTTP clients accept this certificate, while others do not. what's the difference? Java rejects it. ((javax.net.ssl.HttpsURLConnection)new java.net.URL("https://www.lucidpress.com") .openConnection()) .getInputStream() javax.net.ssl.SS

Some SSL certificates in chromium don't work

Benjamin I don't know what's going on, or how to fix this. When I browse to sites like Amazon or Bandcamp, I find one of those bugs in Your connection is not privatechrome . Strangely, when I switch to using FireFox, I can load those sites just fine (and accep

Client-Side SSL with Intermediate Certificates

Naftuli Kay I have a self signed root certificate and an intermediate certificate signed by that root. Basically something like this: . └── master (CA) └── servant1 (CA) I have some client certificates from master->servant1certificate chain : . └── master

Client-Side SSL with Intermediate Certificates

Naftuli Kay I have a self signed root certificate and an intermediate certificate signed by that root. Basically something like this: . └── master (CA) └── servant1 (CA) I have some client certificates from master->servant1certificate chain : . └── master

How to allow specific SSL client certificates in Nginx?

Joe White Nginx ssl_client_certificateand ssl_trusted_certificatedirectives can be used to allow client certificates signed by a given authority. But how to allow specific certificates? I want to filter by certificate thumbprint or by certificate authority + c

NGINX uses client certificates (ssl_verify_client)

TDawg I have a weird question, I don't even know how to phrase it, but I tried my best I use laravel forge to manage my SSL via LetsEncrypt. It generates the file: server.crt server.key How to get .pem files from .key and .crt files? Based on that link, I u

What makes some SSL certificates "better" than others?

Kevin I understand that browsers must trust a certificate authority (CA) to display pages with an SSL certificate without the website visitor trusting the certificate. But I've seen certificates sold at different prices by different companies ( some are even f

What makes some SSL certificates "better" than others?

Kevin I understand that browsers must trust a certificate authority (CA) to display pages with an SSL certificate without the website visitor trusting the certificate. But I've seen certificates sold at different prices by different companies ( some are even f