Recently, I was getting this error while deploying the SharePoint Provider hosted app in Azure app service.

Exact Error:

The underlying connection was closed: An unexpected error occurred on a send. Innerer Exception System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. —> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

Then, I started debugging locally with username and password and still getting error while generating token as shown:

Token request failed. Innerer Exception System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.GetResponse()
at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2WebRequest.GetResponse()
at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue(String securityTokenServiceUrl, OAuth2AccessTokenRequest oauth2Request)

Above error message gave me some hints and issue is related with security protocol.

Solution: After a bit of research, I found that this error was happening only in older applications. This can be fixed by updating the security protocal.

we need add following code before doing authentication or generating token.

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

We can add this line of code just before authentication part as shown. (sample)

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var webContext = new HttpContextWrapper(HttpContext.Current);
var spContext = SharePointContextProvider.Current.GetSharePointContext(webContext);

if (HttpContext.Current.Session["accessToken"] == null)
    HttpContext.Current.Session["accessToken"] = spContext.UserAccessTokenForSPHost;

Alternatively, for manual authentication (sample)

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Uri siteUri = new Uri(siteUrl);
var ll = siteUri.UserInfo;
string realm = TokenHelper.GetRealmFromTargetUrl(siteUri);
string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUri.Authority, realm).AccessToken;

However, if you are creating the provider hosted app with latest version, then this issue already fixed.

King Regards