Hadar Grubman
Hadar Grubman

Reputation: 314

How to authenticate by smart card as a fallback to windows authentication in httpClint/httpListener

I'm using Owin to self host a web application.

The authentication scheme defined at the server is as follows:

HttpListener listener = (HttpListener)app.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;

My client's code looks like:

using (var webRequestHandler = new WebRequestHandler {UseDefaultCredentials = true})
using (var httpClient = new HttpClient(webRequestHandler))
{
    var responseCode = httpClient.PostAsync("https://server:443/myapi/dosomething/", null).Result.StatusCode;
    Console.WriteLine(responseCode == HttpStatusCode.OK ? "Success" : "Failure");
}

This works great when the logged-on user on the client's machine is a user known by the server's machine.

The problems begin when, for example, the client's machine is not domain joined and the client is run by a local user. In that case, I have extended my client a bit, as follows:

HttpStatusCode responseCode;
using (var webRequestHandler = new WebRequestHandler {UseDefaultCredentials = true})
using (var httpClient = new HttpClient(webRequestHandler))
{
    responseCode = httpClient.PostAsync("https://server:443/myapi/dosomething/", null).Result.StatusCode;
}

if (responseCode == HttpStatusCode.Unauthorized)
{
    string username;
    string password;
    // prompt user for credentials and store them at the above variables

    using (var webRequestHandler = new WebRequestHandler { Credentials = new NetworkCredential(username, password)})
    using (var httpClient = new HttpClient(webRequestHandler))
    {
        responseCode = httpClient.PostAsync("https://server:443/myapi/dosomething/", null).Result.StatusCode;
    }
}
Console.WriteLine(responseCode == HttpStatusCode.OK ? "Success" : "Failure");

And this solves it, but I'm limited to perform the fallback authentication using username/password only.

My problem is that I need to support smart card authentication as well as username/password authentication.

Upvotes: 3

Views: 1151

Answers (1)

Pedro Felix
Pedro Felix

Reputation: 1076

Assuming that "smart card authentication" is done via client-side certificates, you can enable this feature either by:

  • configuring HttpClient to automatically select a certificate

    var client = new HttpClient(
        new HttpClientHandler{
            ClientCertificateOptions = ClientCertificateOption.Automatic
        });
    
  • or by configuring HttpClient with a previously selected certificate

    var clientHandler = new WebRequestHandler();
    clientHandler.ClientCertificates.Add(cert);
    var client = new HttpClient(clientHandler);
    

where cert is a certificate with an associated private key.

You can read more about this on Client Authentication

Upvotes: 1

Related Questions