ASP.NET 核心 Restful Web API Https - 客户端连接证书错误
ASP.NET Core Restful Web API Https - Client Connection Certificate Errors
我构建了一个使用 JWT 进行身份验证的 ASP.NET Core 3.1 Web API;发布项目并部署到 Windows 2019 服务器 运行ning IIS。
我在 IIS 中创建了如下站点:
创建了新的应用程序池,'No Managed Code' 作为 .NET CLR 版本。通常网站 运行 在 IIS 工作进程中,但在 .NET Core 中它们 运行 作为一个单独的进程,因此应用程序池中不需要 .NET 运行时。
为我的 ASP.NET 核心应用程序创建了一个新网站:选择之前创建的应用程序池,将物理路径设置为包含已发布应用程序的文件夹,选择 HTTPS 作为绑定并还在 SSL 证书下拉列表中选择证书到我从 Comodo 获得的证书。我还设置了主机名并将 'Require server name indication' 设置为 true - 因为我有旧版 WCF 站点,它们具有不同的主机名但位于同一 IP 上。
在 Postman 中,当我发送启用了 SSL 证书验证的请求时,我收到 SSL 错误:Hostname/IP 与证书的 altnames 不匹配。关闭 SSL 验证后,它可以正常工作。
使用 HttpClient 创建 .NET 桌面客户端并向站点发送请求时出现错误:基础连接已关闭:无法为 SSL/TLS 安全建立信任关系频道.
当我 Google 这个问题时,我发现大部分文章与人们在开发环境中使用自签名证书有关。
如果我将以下代码添加到我的客户端,它可以正常工作:
if (http_client == null)
{
var handler = new HttpClientHandler()
{
AllowAutoRedirect = false,
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
};
http_client = new HttpClient(handler);
}
为什么我会收到这些 SSL 错误?我的站点配置不正确吗? 我想尽快向开发人员提供对该站点的访问权限,但我担心他们在连接时会遇到问题。有些将从 iOS 环境连接,其他则来自不同的网站服务器平台。
Startup.cs 网络 API
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddControllers().AddJsonOptions(x => x.JsonSerializerOptions.IgnoreNullValues = true);
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
// configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
// set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
ClockSkew = TimeSpan.Zero
};
});
// configure DI for application services
services.AddScoped<IUserService, UserService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseHttpsRedirection();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
gFunc.SetFolderPaths(true);
}
// global cors policy
app.UseCors(x => x
.SetIsOriginAllowed(origin => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(x => x.MapControllers());
}
如我的 OP 中所述,我之前 运行 在 IIS 上只设置了一个站点,该站点提供一些遗留 WCF 服务。然后,我在同一 IP 地址上为 .NET Core Web API 添加了另一个站点。为此,我必须在 IIS 中为新站点启用服务器名称指示 (SNI)。
但是,我发现在使用 SNI 时,您必须为所有网站打开它,而不仅仅是一个。我在服务器上使用 ssllabs.com 到 运行 测试,它返回 证书名称不匹配 ,并返回另一个 domain/hostname 的证书。
运行 服务器上的“netsh http show sslcert”显示了两个证书,但 WCF 站点的证书未链接到主机名 - 仅链接到 IP 地址。因此,任何进入该 IP 地址的请求都只会获得该证书。
为另一个 (WCF) 站点启用 SNI 解决了这个问题。现在每个证书都绑定到 IP/Hostname.
我构建了一个使用 JWT 进行身份验证的 ASP.NET Core 3.1 Web API;发布项目并部署到 Windows 2019 服务器 运行ning IIS。
我在 IIS 中创建了如下站点:
创建了新的应用程序池,'No Managed Code' 作为 .NET CLR 版本。通常网站 运行 在 IIS 工作进程中,但在 .NET Core 中它们 运行 作为一个单独的进程,因此应用程序池中不需要 .NET 运行时。
为我的 ASP.NET 核心应用程序创建了一个新网站:选择之前创建的应用程序池,将物理路径设置为包含已发布应用程序的文件夹,选择 HTTPS 作为绑定并还在 SSL 证书下拉列表中选择证书到我从 Comodo 获得的证书。我还设置了主机名并将 'Require server name indication' 设置为 true - 因为我有旧版 WCF 站点,它们具有不同的主机名但位于同一 IP 上。
在 Postman 中,当我发送启用了 SSL 证书验证的请求时,我收到 SSL 错误:Hostname/IP 与证书的 altnames 不匹配。关闭 SSL 验证后,它可以正常工作。
使用 HttpClient 创建 .NET 桌面客户端并向站点发送请求时出现错误:基础连接已关闭:无法为 SSL/TLS 安全建立信任关系频道.
当我 Google 这个问题时,我发现大部分文章与人们在开发环境中使用自签名证书有关。
如果我将以下代码添加到我的客户端,它可以正常工作:
if (http_client == null)
{
var handler = new HttpClientHandler()
{
AllowAutoRedirect = false,
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
};
http_client = new HttpClient(handler);
}
为什么我会收到这些 SSL 错误?我的站点配置不正确吗? 我想尽快向开发人员提供对该站点的访问权限,但我担心他们在连接时会遇到问题。有些将从 iOS 环境连接,其他则来自不同的网站服务器平台。
Startup.cs 网络 API
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddControllers().AddJsonOptions(x => x.JsonSerializerOptions.IgnoreNullValues = true);
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
// configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
// set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
ClockSkew = TimeSpan.Zero
};
});
// configure DI for application services
services.AddScoped<IUserService, UserService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseHttpsRedirection();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
gFunc.SetFolderPaths(true);
}
// global cors policy
app.UseCors(x => x
.SetIsOriginAllowed(origin => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(x => x.MapControllers());
}
如我的 OP 中所述,我之前 运行 在 IIS 上只设置了一个站点,该站点提供一些遗留 WCF 服务。然后,我在同一 IP 地址上为 .NET Core Web API 添加了另一个站点。为此,我必须在 IIS 中为新站点启用服务器名称指示 (SNI)。
但是,我发现在使用 SNI 时,您必须为所有网站打开它,而不仅仅是一个。我在服务器上使用 ssllabs.com 到 运行 测试,它返回 证书名称不匹配 ,并返回另一个 domain/hostname 的证书。
运行 服务器上的“netsh http show sslcert”显示了两个证书,但 WCF 站点的证书未链接到主机名 - 仅链接到 IP 地址。因此,任何进入该 IP 地址的请求都只会获得该证书。
为另一个 (WCF) 站点启用 SNI 解决了这个问题。现在每个证书都绑定到 IP/Hostname.