我想创建一个简单的SignalR应用程序。 使用http一切正常,但当我尝试使用https和证书时,应用程序无法正常工作。
目前,我唯一想做的就是在服务器上获取客户端证书。
服务器(身份验证处理程序):
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;
}
}
客户(集线器)
var connection = new HubConnection("https://localhost:8080/");
connection.AddClientCertificate(X509Certificate.CreateFromCertFile("c1.cer"));
IHubProxy myHub = connection.CreateHubProxy("MyHub");
connection.Start().Wait();
执行此操作,当我执行var cert = Context.Get<X509Certificate>("ssl.ClientCertificate");
时,我会在服务器中获取null
。
那么,我做错了什么?
答案 0 :(得分:4)
您还必须告诉IIS使用客户端证书。在web.config
执行:
<location path="signalr">
<system.webServer>
<security>
<access sslFlags="SslNegotiateCert" />
</security>
</system.webServer>
</location>
我的工作代码
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);
和
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");
}