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?
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");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With