我试图从服务器代码调用我的signalR hub方法并且它给我一个错误
无法为SSL / TLS安全通道建立信任关系。
我的服务器端代码是这样的
private void InvokeNotification(string methodName, params object[] args)
{
try
{
string serverIp = ConfigurationManager.AppSettings["ServerIp"];
var connection = new HubConnection(serverIp, useDefaultUrl: true);
var myHub = connection.CreateHubProxy("myhub");
connection.Start().Wait();
myHub.Invoke(methodName, args);
}
catch (Exception ex)
{
//Some error handling
}
}
在集线器类中,我有一个方法,例如SayHello()
,它向所有用户发送消息。
使用http工作完美,但是当我从IIS绑定中删除80
端口,并且只保留https端口时,每次尝试Start()
集线器连接时都会给我错误。我尝试了许多通过搜索找到的东西,但没有这些东西。
有没有其他人有类似的问题,请帮助。
答案 0 :(得分:2)
好的,我做了像这样的事情
private void InvokeNotification(string methodName, params object[] args)
{
try
{
string serverIp = ConfigurationManager.AppSettings["ServerIp"];
var connection = new HubConnection(serverIp, useDefaultUrl: true);
var myHub = connection.CreateHubProxy("myhub");
//This will ignore all certeficates
//System.Net.ServicePointManager.ServerCertificateValidationCallback =
// ((sender, certificate, chain, sslPolicyErrors) => true);
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
connection.Start().Wait();
myHub.Invoke(methodName, args);
}
catch (Exception ex)
{
//Some error handling
}
}
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert,
X509Chain chain, SslPolicyErrors policyErrors)
{
bool result = false;
if (cert.Subject.ToUpper().Contains("MY_CERT_ISSUER_NAME"))
{
result = true;
}
return result;
}
通过这个,我找到了我的证书并在SSL对话中手动验证(实际通过)它。我不知道这个解决方案有多大合法性,但现在却是。
我改变了ValidateRemoteCertificate()
方法:
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert,
X509Chain chain, SslPolicyErrors policyErrors)
{
bool result = false;
X509Certificate2 cert2 = (X509Certificate2)cert;
X509Store store = new X509Store(StoreName.Root);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection cc = store.Certificates.Find(X509FindType.FindByThumbprint,
chain.ChainElements[chain.ChainElements.Count - 1].Certificate.Thumbprint, true);
store.Close();
if (cc.Count > 0)
{
result = true;
}
return result;
}
通过这个我打开证书商店,通过从证书链(最后一个元素)传递thumbprint参数,从中找到我的项目。
答案 1 :(得分:1)
验证证书的另一种方法是:
static internal class SSLCertificateResolverConfigurator
{
static internal void Setup()
{
ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
}
static private bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors) //0
{
if (policyErrors == SslPolicyErrors.None)
return true;
var thumbprint = chain.ChainElements.Count > 0 ? chain.ChainElements[chain.ChainElements.Count - 1].Certificate.Thumbprint : null;
if (thumbprint == null) //somethings wrong
return false;
var sha1CertHashString = certificate.GetCertHashString();
if (sha1CertHashString == null) //somethings wrong
return false;
if (ApprovedCertificatesSHA1Cache.ContainsKey(sha1CertHashString))
return true;
try
{
var asCertificate2 = certificate as X509Certificate2 ?? new X509Certificate2(certificate);
X509CertificateValidator.ChainTrust.Validate(asCertificate2); //1
ApprovedCertificatesSHA1Cache.TryAdd(sha1CertHashString, sha1CertHashString);
return true;
}
catch
{
return false;
}
//0 vital for signalr to work via https https://stackoverflow.com/questions/44433067/signalr-could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel
//1 chaintrust checks both personal account specific certificates and the trusted root certificates authorities
}
static private readonly ConcurrentDictionary<string, string> ApprovedCertificatesSHA1Cache = new ConcurrentDictionary<string, string>();
}
必须将其插入Global.asax.cs的Application_Start()(Owin的启动也可以):
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
[...]
SSLCertificateResolverConfigurator.Setup();
}
}
// for instructions on enabling IIS6 or IIS7 classic mode visit http://go.microsoft.com/?LinkId=9394801