Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR with Certificates

I want to create a simple SignalR application. Using http everything works fine, but when i try to use https and certificates the application don't work.

For now, the only thing i want to do is get the Client's Certificate in the server.

Server (Authentication Handler):

 public class ClientCertificateAuthenticationHandler : AuthenticationHandler<ClientCertificateAuthenticationOptions>
{
    protected override Task<AuthenticationTicket> AuthenticateCoreAsync()
    {
        var cert = Context.Get<X509Certificate>("ssl.ClientCertificate");

        if (cert == null)
        {
            return Task.FromResult<AuthenticationTicket>(null);
        }

        try
        {
            Options.Validator.Validate(cert);
        }
        catch
        {
            return Task.FromResult<AuthenticationTicket>(null);
        }
        return null;
    }
}

Client (Hub)

var connection = new HubConnection("https://localhost:8080/");
connection.AddClientCertificate(X509Certificate.CreateFromCertFile("c1.cer"));
IHubProxy myHub = connection.CreateHubProxy("MyHub");
connection.Start().Wait();

Doing this, in the server when i do var cert = Context.Get<X509Certificate>("ssl.ClientCertificate"); i get null.

So, what i'm doing wrong?

like image 206
nuno.filipesf Avatar asked Sep 29 '22 16:09

nuno.filipesf


1 Answers

You also have to tell IIS to use the client certificate. In web.config do:

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

my working code

var cert = ServiceCallHelper.GetClientCertificate();
var url = new Uri(Settings.CoreUrl);
var str = String.Format("https://{0}/cert_signalr", url.Host);
var hub = new HubConnection(str, false);
hub.AddClientCertificate(cert);

and

object cert = null;
if (!hub.Context.Request.Environment.TryGetValue("ssl.ClientCertificate", out cert) ||
   !(cert is X509Certificate2))
{
   s_logger.WarnFormat("Hub {0} called without certificate or cookie", hub.Context.Request.ToString());
   throw new Exception("not authenticated");
}
like image 53
pm100 Avatar answered Oct 23 '22 06:10

pm100