我在尝试发出POST请求时遇到“接收”错误。
我知道它与TLS或SSL有关,但是我无法确切查明我的代码是否有问题。添加行ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
时,我已经研究了将近99%的答案,但是该行仅帮助错误不再从“发送时发生意外错误”变为“接收时发生意外错误”。我的代码如下:
我正在使用Windows Server 2012 R2。
public static void Request()
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
try
{
string serverURI = "xxxx";
string relativeURI = "xxxx";
Uri serverURL = new Uri(serverURI, UriKind.Absolute);
Uri relativeURL = new Uri(relativeURI, UriKind.Relative);
string defaultUsername = "xxxx";
string defaultPass = "xxxx";
//Add URL To send request to
HttpWebRequest oktaLoginRequest = (HttpWebRequest)WebRequest.Create(new Uri(serverURL, relativeURI));
oktaLoginRequest.ContentType = "application/x-www-form-urlencoded";
oktaLoginRequest.Accept = "application/json";
string encoded = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(defaultUsername + ":" + defaultPass));
oktaLoginRequest.Headers.Add("Authorization", "Basic " + encoded);
string requestBody = "grant_type=password&username=xxxx&password=xxxx!&scope=openid";
oktaLoginRequest.Method = "POST";
//Set up our body request
Stream requestStream = oktaLoginRequest.GetRequestStream();
byte[] postBytes = Encoding.UTF8.GetBytes(requestBody);
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)oktaLoginRequest.GetResponse();
string result;
using (StreamReader rdr = new StreamReader(response.GetResponseStream()))
{
result = rdr.ReadToEnd();
Console.WriteLine(result);
}
}
catch (Exception exception1)
{
Console.WriteLine(exception1.ToString());
}
Console.ReadLine();
}
我在此行出现错误:HttpWebResponse response = (HttpWebResponse)oktaLoginRequest.GetResponse();
我还尝试了使用HttpClient对象的相同代码。我收到完全相同的错误。代码如下:
private static readonly HttpClient client = new HttpClient();
public async static void Request3()
{
try
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
string defaultUsername = "xxxx";
string defaultPass = "xxxx";
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.TryAddWithoutValidation("content-type", "application/x-www-form-urlencoded");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{defaultUsername}:{defaultPass}")));
client.DefaultRequestHeaders.ExpectContinue = false;
string url = "xxx.com/oauth2/default/v1/token";
Uri URL = new Uri(url);
var values = new Dictionary<string, string>
{
{ "application/x-www-form-urlencoded", "grant_type=password&username=xxx&password=xxx!&scope=openid" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync(URL, content);
var responseString = await response.Content.ReadAsStringAsync();
//var responseString = await client.GetStringAsync(URL.AbsoluteUri);
Console.WriteLine(responseString);
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
Console.ReadLine();
}
完整的错误是:
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.ComponentModel.Win32Exception: The client
and server cannot communicate, because they do not possess a common algorithm
at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule, S
tring package, CredentialUse intent, SecureCredential scc)
at System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse c
redUsage, SecureCredential& secureCredential)
at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPr
int)
at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset
, Int32 count, Byte[]& output)
at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offse
t, Int32 count)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, A
syncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byt
e[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyRes
ult)
at System.Net.TlsStream.CallProcessAuthentication(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionCo
ntext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C
ontextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C
ontextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetResponse()
at TestOkta.Program.Request() in C:\Users\prvrzaidi\source\repos\TestOkta\Tes
tOkta\Program.cs:line 58
谢谢。