CSharp使用WebRequest请求HTTPS遇到的问题
起因
由于前几天心血来潮,升级了Linux系统和Jexus,阿里云ecs购买了四年,一直都是测试练手的.又重新配置了Jexus,将tls版本改为tls 1.2.今天在用WebRequest请求的时候.遇到身份验证失败的错误.由于项目设置的是.Net Framework 4.0
string url = "https://www.qiufengblog.com/sitemap.xml";
if (url.StartsWith("https"))
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => { return true; };
}
在SecurityProtocolType枚举下,只有两项
public enum SecurityProtocolType
{
//
// 摘要:
// 指定安全套接字层 (SSL) 3.0 安全协议。
Ssl3 = 48,
//
// 摘要:
// 指定传输层安全 (TLS) 1.0 安全协议。
Tls = 192
}
所以上面请求代码,选择SecurityProtocol.Tls,在请求的时候,还是要报身份验证失败.才想起是不是Framework版本太低.将Framework版本改为4.6.2.发现SecurityProtocol枚举有Tls12选项.
完整代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.IO;
using System.Text;
namespace qiufeng.tools
{
static class Program
{
static void Main(string[] args)
{
string url = "https://www.qiufengblog.com/sitemap.xml";
if (url.StartsWith("https"))
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //主要选择对应tls版本
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => { return true; };
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = null;
try
{
response = request.GetResponse() as HttpWebResponse;
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
string content = reader.ReadToEnd();
string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sitemap.xml");
File.WriteAllText(file, content, Encoding.UTF8);
}
}
}
catch (WebException ex)
{
response = (HttpWebResponse)ex.Response;
Console.WriteLine("statuscode ={0}", response.StatusCode);
}
finally
{
if (response != null)
{
response.Close();
}
}
}
}
}
以上代码,在Windows是没问题的.在Linux运行的时候,还要在多执行一步.是因为Linux默认没又根证书.使用mono自带的mozroots工具.如果系统没有安装mono,使用的是Jexus独立版,在Jexus执行的根目录中带有这个工具.
这里以mono安装为例: 先手动查找mozroots所在位置
若是在想web程序全局配置的话
如果你是在web程序中,只想配置一次的话,请求其他https地址的话,代码要设置tls版本和验证证书回调.
webform和mvc(不包含asp.net core mvc):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
namespace WebApplication1
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; //根据自己需要选择对应的
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => { return true; };
}
}
}
Nancy的话在Bootstrapper配置ApplicationStartup:
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; //根据自己需要选择对应的
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => { return true; };
//其他处理
//.....
}
秋风
2018-04-22