How to use SSL encryption and achieve communication between the client and server of SignalR with C#

Aspire 81 Reputation points
2023-11-20T08:41:37.7733333+00:00

I'm new for SignalR and I have one application using C#.

The basic connection code for the SignalR client and server implemented by the Net Framework is as follows:

Client

using Microsoft.AspNet.SignalR.Client;
namespace WinFormsClient
{
    public partial class FrmClient : Form
    {
        //Connection to a SignalR server
        HubConnection _signalRConnection;

        //Proxy object for a hub hosted on the SignalR server
        IHubProxy _hubProxy;
        private async Task connectAsync()
        {
            //Set Certificate callback
            ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
            //Create a connection for the SignalR server
            _signalRConnection = new HubConnection("https://10.224.10.10:12316/signalr/SimpleHub/");
            _signalRConnection.StateChanged += HubConnection_StateChanged;
            _signalRConnection.Closed += HubConnection_Closed;

            //Get a proxy object that will be used to interact with the specific hub on the server
            //Ther may be many hubs hosted on the server, so provide the type name for the hub
            _hubProxy = _signalRConnection.CreateHubProxy("SimpleHub");

            //Reigster to the "AddMessage" callback method of the hub
            //This method is invoked by the hub
            _hubProxy.On<string, string>("AddMessage", (name, message) => writeToLog($"{name}:{message}"));            

            try
            {
                //Connect to the server
                await _signalRConnection.Start();

                //Send user name for this client, so we won't need to send it with every message
                await _hubProxy.Invoke("SetUserName", txtUserName.Text);
            }
            catch (Exception ex)
            {
                writeToLog($"Error:{ex.Message}");
            }
        }
        private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErros)
        {
            return true;
        }
    }
}

Server

using Microsoft.Owin.Hosting;
using Microsoft.AspNet.SignalR;
using System.ComponentModel;

namespace WinFormsServer
{
    public partial class FrmServer : Form
    {
        private IDisposable _signalR;
        private void btnStartServer_Click(object sender, EventArgs e)
        {
            try
            {
                //Start SignalR server with the give URL address
                //Final server address will be "URL/signalr"
                //Startup.Configuration is called automatically
                _signalR = WebApp.Start<Startup>("https://localhost:12316");
                writeToLog($"Server started at:{txtUrl.Text}");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
using Owin;
using Microsoft.Owin.Cors;

namespace WinFormsServer
{
    class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            //CORS need to be enabled for calling SignalR service 
            app.UseCors(CorsOptions.AllowAll);
            //Find and reigster SignalR hubs
            app.MapSignalR();
        }
    }
}

Now, I deploy the client and server on the same machine and bind a self signed SSL certificate to the specified IP and ports through the following statement. Netsh http add sslcert ipport=10.224.10.10:12316 certificate=xxxx appid={xxxx}

Then I tried to start the server and it ran normally. When I try to start the client to connect to the server, I am prompted with the following error:

StatusCode:400, ReasonPhrase:'Bad Request', Version: 1.1, Content: System.Net.Http.SteamContent, Headers:
{
    Connection: close
    Data: Mon, 20 Nov 2023 04:41:15 GMT
    Server: Microsoft-HTTPAPI/2.0
    Content-Length:334
    Content-Type:text/html; charset=us-ascii
}

I have imported the self signed certificate into the Personal and Trusted Root Certification Authorities of the MMS Console Root, as well as into the Local Computer and Current User. I don't know why the client can't connect to the server. Can someone help me?

Besides, If I change the server-side URL to https://10.224.10.10:12316/ , will prompt that the server failed to start, Inner Exception HttpListenerException: Access is denied. I added the service name and bound Port 12316 in the local Inbound Rules. Do I need to configure anything else?

Azure SignalR Service
Azure SignalR Service
An Azure service that is used for adding real-time communications to web applications.
146 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,995 questions
{count} votes

1 answer

Sort by: Most helpful
  1. brtrach-MSFT 16,506 Reputation points Microsoft Employee
    2023-11-22T01:30:18.06+00:00

    @Aspire The error message you are receiving indicates that there is an issue with the request being sent from the client to the server.

    To troubleshoot this issue, you can try the following steps:

    1. Verify that the SSL certificate is installed correctly on both the server and client machines. You can use the certmgr.msc tool to verify if the certificate is installed in the correct location.
    2. Ensure that the SSL certificate is trusted by the client machine. You can use the certmgr.msc tool to verify if the certificate is trusted by the client machine.
    3. Confirm that the SSL certificate is valid and has not expired. You can use the certmgr.msc tool to verify if the certificate is valid.

    Check if the SSL certificate is bound to the correct IP address and port. You can use the netsh http show sslcert command to verify if the certificate is bound to the correct IP address and port.

    Regarding the issue with the server failing to start when you change the server-side URL to https://10.224.10.10:12316/, it seems that there is an issue with the permissions for the HTTP listener. You can try running the server with elevated privileges to see if that resolves the issue.

    Alternatively, you can consider using Azure SignalR Service to simplify the process of setting up a secure connection between the SignalR client and server. Azure SignalR Service provides built-in support for SSL encryption and can be easily integrated with your existing SignalR application.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.