【问题标题】:How to make an HTTP Get request along with SslStream & TcpClient如何与 SslStream 和 TcpClient 一起发出 HTTP Get 请求
【发布时间】:2019-09-22 00:20:27
【问题描述】:

在我的应用程序中,我使用以下代码来验证客户端证书

public static async Task<string> CallApi(string url, Context context)
{
    var hostName = "mytestapp.azurewebsites.net";
    var port = 443;

    Stream keyin = Application.Context.Assets.Open("Server.pfx");
    var password = "pass123";
    using (MemoryStream memStream = new MemoryStream())
    {
        keyin.CopyTo(memStream);
        var certificates = new X509Certificate2Collection(new X509Certificate2(memStream.ToArray(), password));
        await Task.Run(() =>
        {
            // Create a TCP/IP client socket.
            // machineName is the host running the server application.
            TcpClient client = new TcpClient(hostName, port);
            Console.WriteLine("Client connected.");
            // Create an SSL stream that will close the client's stream.
            SslStream sslStream = new SslStream(
                client.GetStream(),
                false,
                ValidateServerCertificate);

            // The server name must match the name on the server certificate.
            try
            {
                sslStream.AuthenticateAsClient(hostName, certificates, SslProtocols.Tls12, true);
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                }
                Console.WriteLine("Authentication failed - closing the connection.");
                client.Close();
                return;
            }
        });
    }

    return string.Empty;
}

认证成功后,我想发出HTTP get请求。

sslStream.AuthenticateAsClient(hostName, certificates, SslProtocols.Tls12, true);

在此声明之后。比如说我需要在下面调用 http Get call

https://mytestapp.azurewebsites.net/api/GetUserProfile?userId="Sooraj"

如何调用此调用?或者是否有可能实现相同的?

请帮忙

【问题讨论】:

  • 使用 WebClient 可能比您自己的 TcpClient 更容易。您可以允许 WebClient 使用证书和 SSL。示例:stackoverflow.com/questions/2066489/…
  • 另一种选择可能是 HttpWebRequest。这是带有客户端证书的示例:stackoverflow.com/questions/39528973/…
  • 否则,如果你继续使用TcpClient,我相信你需要编写自己的HTTP头和请求流,并手动解析响应。
  • 很遗憾我正在使用 Mono / Xamarin。我无法使用 WebClient。 Mono.Net 中存在一个已知限制
  • 能否请您告诉我有关继续使用 TCP 客户端的更多信息。

标签: c# .net tcpclient sslstream


【解决方案1】:

试试这样的,

try
                    {
                        sslStream.AuthenticateAsClient(hostName, certificates, SslProtocols.Tls12, true);

                        byte[] buffer = new byte[5120];
                        int bytes;
                        var pqr = string.Format("GET {0}  HTTP/1.1\r\nHost: {1}\r\n\r\n", url, "mytestapp.azurewebsites.net");
                        byte[] request = Encoding.UTF8.GetBytes(pqr);
                        sslStream.Write(request, 0, request.Length);
                        var ppp =  ReadStream(sslStream);
                        sslStream.Flush();

                    }
                    catch (AuthenticationException e)
                    {
                        Console.WriteLine("Exception: {0}", e.Message);
                        if (e.InnerException != null)
                        {
                            Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                        }
                        Console.WriteLine("Authentication failed - closing the connection.");
                        client.Close();
                        return;
                    }


 private static string ReadStream(Stream stream)
        {
            byte[] resultBuffer = new byte[2048];
            string value = "";
            //requestStream.BeginRead(resultBuffer, 0, resultBuffer.Length, new AsyncCallback(ReadAsyncCallback), new result() { buffer = resultBuffer, stream = requestStream, handler = callback, asyncResult = null });
            do
            {
                try
                {
                    int read = stream.Read(resultBuffer, 0, resultBuffer.Length);
                    value += Encoding.UTF8.GetString(resultBuffer, 0, read);

                    if (read < resultBuffer.Length)
                        break;
                }
                catch { break; }
            } while (true);
            return value;
        }

它将为您提供所有数据集的响应。稍后我们需要解析所需的信息。

【讨论】:

    猜你喜欢
    • 2017-05-04
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多