我有一个使用 Nginx 作为反向代理运行的 .net 核心应用程序,当我尝试使用 Facebook 登录时出现此错误:
标头中的非 ASCII 或控制字符无效:0x000D
在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.ThrowInvalidHeaderCharacter(Char ch) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.ValidateHeaderValueCharacters(StringValues& headerValues) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseHeaders.SetValueFast(String key, StringValues& value) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.Microsoft.AspNetCore.Http.IHeaderDictionary.set_Item(String key, StringValues value) 在 Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.Redirect(String location, Boolean permanent) 在 Microsoft.AspNetCore.Http.HttpResponse.Redirect(String location) 在gringomvc.Startup.RemoteAuthFail(RemoteFailureContext context) 位于 C:\Users\Offir\Documents\Source\Repos\gringomvc\gringomvc\Startup.cs:line 35 位于 Microsoft.AspNetCore.Authentication.RemoteAuthenticationEvents.RemoteFailure(RemoteFailureContext context) 位于 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync() 位于 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) 位于 Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context) 位于 Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context) 位于 Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext 上下文)
在我使用 IIS express 的开发环境中,我没有收到此错误,只使用了 Nginx。
启动.cs:
public class Startup
{
private IConfiguration _config;
public Startup(IConfiguration config)
{
_config = config;
}
private Task RemoteAuthFail(RemoteFailureContext context)
{
context.Response.Redirect("/Error/ErrorLogin?message=" + context.Failure.Message);
context.HandleResponse();
return Task.CompletedTask;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-2.2
//https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.0
//https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/#how-to-use-it-in-nginx
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddDbContext<testContext>(options => options.UseSqlServer(_config.GetConnectionString("DefaultConnection")));
services.AddAuthentication(options =>
{
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = "Temporary";
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddFacebook(options =>
{
options.AppId = "2235597157716847";
options.AppSecret = "03daab4e1c16cecc728bd83e9da1e3af";
options.Events.OnRemoteFailure = RemoteAuthFail;
})
.AddCookie(options =>
{
options.LoginPath = "/auth/signin";
})
.AddCookie("Temporary");
services.AddMemoryCache();
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization()
.AddRazorOptions(opt =>
{
opt.ViewLocationFormats.Add("/Views/{1}/Partials/{0}.cshtml");
opt.ViewLocationFormats.Add("/Views/Shared/Partials/{0}.cshtml");
});
services.AddBreadcrumbs(GetType().Assembly);
services.AddScoped<ICacheRepository, CacheRepository>();
services.AddScoped<ILocationService, LocationService>();
services.AddScoped<IBusinessService, BusinessService>();
services.AddScoped<IUserService, UserService>();
services.AddScoped<ITipService, TipService>();
services.AddScoped<ITextService, TextService>();
services.AddScoped<ISeoService, SeoService>();
services.AddScoped<IImageService, ImageService>();
services.AddScoped<ICategoryService, CategoryService>();
services.AddScoped<ICommentService, CommentService>();
services.AddScoped<IContactUsService, ContactUsService>();
services.AddScoped<ISearchService, SearchService>();
services.AddScoped<IInfoService, InfoService>();
services.AddScoped<ILoggerService, LoggerService>();
#region localization
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("he")
//new CultureInfo("en"),
//new CultureInfo("es")
};
options.DefaultRequestCulture = new RequestCulture("he");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
#endregion
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//Getting the forward headers from Nginx like we define above
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
// Handle unhandled errors
app.UseExceptionHandler("/Error");
app.UseStatusCodePagesWithReExecute("/Error/{0}");
//keep it - not related to the error handling.
app.UseHsts();
}
#region Localization2
var supportedCultures = new[]
{
new CultureInfo("he")
//new CultureInfo("en"),
//new CultureInfo("es")
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("he"),
// Formatting numbers, dates, etc.
SupportedCultures = supportedCultures,
// UI strings that we have localized.
SupportedUICultures = supportedCultures
});
#endregion
//redirect site to https
app.UseHttpsRedirection();
//use wwwroot for fetching static files
app.UseStaticFiles();
// To configure external authentication,
// see: http://go.microsoft.com/fwlink/?LinkID=532715
app.UseAuthentication();
//Request Localization
app.UseRequestLocalization();
app.UseMvcWithDefaultRoute();
}
}
Nginx 配置文件:
server {
listen 80;
server_name example.co.il *.example.co.il;
location / {
proxy_pass http://localhost:5000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Nginx 访问日志:
162.158.154.200 - - [28/Sep/2019:13:30:53 +0000] "GET /signin-facebook?code=AQAKt8zNTbedUb8LKnsuBZpG-eCA_77sfnic6jt_TPE36C7e46MUhFs0i_ZU29PA2qbOClyXdaz6NfA0JW5NcpF6cnLJ4Nd6b7JjGa51-YOiLvKGavUbsAjEQpIOCdQ7cXcx8dOUlyDP5oU-knAi28U-mBfbiurFUv-laYOJY1UMqRIxRrVJKaZ4LwRIHm41d8w0yky0-bOEJPhBvK0mYmBBO86drYsXnOnY-stosIfCxS82D_q0ffJoijelXJoxNOMnJP8BAq-JhtQScfnroWZXf_ilZLCBmTkvl2va-D9x9SSNM8V7cfgQgdSWO31UnA0&state=CfDJ8OVuvnVG6_9Nphg79v1prru4BxrL9c3MKwcP1buvw6zjIE7TbEk3j76UQE4WHJ2YcodUwMoe0oZwguXeJE_Xjg0WSnq00A2RoBUya2ZEGkiug92j8GhTZwrnMkWdRT6aD0tuKJbOa0_DYFcY07ol5pfxmMYswsyZumW1Z_cCHpi4ZW5yzZm4x7NZll_fCS2DJktUa9rIn-c2nhp4pn3CLuY1TnzzedHQEqQkGY3zpEgsbXXCWFVQB_Hb722FacJfgg HTTP/1.1" 500 186229 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "185.108.83.170"
162.158.154.200 - - [28/Sep/2019:13:30:58 +0000] "GET / HTTP/1.1" 200 34605 "https://example.com/signin-facebook?code=AQAKt8zNTbedUb8LKnsuBZpG-eCA_77sfnic6jt_TPE36C7e46MUhFs0i_ZU29PA2qbOClyXdaz6NfA0JW5NcpF6cnLJ4Nd6b7JjGa51-YOiLvKGavUbsAjEQpIOCdQ7cXcx8dOUlyDP5oU-knAi28U-mBfbiurFUv-laYOJY1UMqRIxRrVJKaZ4LaRIHm41d8w0yky0-bOEJPhBvK0mYmBBO86drYsXnOnY-stosIfCxS82D_q0ffJoijelXJoxNOMnJP8BAq-JhtQScfnroWZXf_ilZLCBmTkvl2va-D9x9SSNM8V7cfgQgdSWO31UmA0&state=CfDJ8OVuvnVG6_9Nphg79v1prru4BxrL9c3MKwcP1buvw6zjIE7TbEk3j76UQE4WHJ2YcodUwMoe0oZzguXeJE_Xjg0WSnq00A2RoBUya2ZEGkiug92j8GhTZwrnMkWdRT6aD0tuKJbOa0_DYFcY07ol4pfxmMYswsyZumW1Z_cCHpi4ZW5yzZm4x7NZll_fCS2DJktUa9rIn-c2nhp4pn3CLuY1TnzzedHQEqQkGY3zpEgsbXXCWFVQB_Hb722FacJfgg" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "185.108.83.170"
Nginx 错误日志:
2019/09/28 13:30:53 [warn] 8571#8571: *3912 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/2/22/0000000222 while reading upstream, client: 162.158.154.200, server: example.com, request: "GET /signin-facebook?code=AQAKt8zNTbedUb8LKnsuBZpG-eCA_77sfnic6jt_TPE36C7e46MUhFs0i_ZU29PA2qbOClyXdaz6NfA0JW5NcpF6cnLJ4Nd6b7JjGa51-YOiLvKGavUbsAjEQpIOCdQ7cXcx8dOUlyDP5oU-knAi28U-mBfbiurFUv-laYOJY1UMqRIxRrVJKaZ4LwRIHm41d8w0yky0-bOEJPhBvK0mYmBBO86drYsXnOnY-stosIfCxS82D_q0ffJoijelXJoxNOMnJP8BAq-JhtQScfnroWZXf_ilZLCBmTkvl2va-D9x9SSNM8V7cfgQgdSWO31UmA0&state=CfDJ8OVuvnVG6_9Nphg79v1prru4BxrL9c3MKwcP1buvw6zjIE7TbEk3j76UQE4WHJ2YcodUwMoe0oZwguXeJE_Xjg0WSnq00A2RoBUya2ZEGkiug92j8GhTZwrnMkWdRT6aD0tuKJbOa0_DYFcY07ol4pfxmMYswsyZumW1Z_cCHpi4ZW5yzZm4x7NZll_fCS2DJktUa9rIn-c2nhp4pn3CLuY1TnzzedHQEqQkGY3zpEgsbXXCWFVQB_Hb722FacJfgg HTTP/1.1", upstream: "http://127.0.0.1:5000/signin-facebook?code=AQAKt8zNTbedUb8LKnsuBZpG-eCA_77sfnic6jt_TPE36C7e46MUhFs0i_ZU29PA2qbOClyXdaz6NfA0JW5NcpF6cnLJ4Nd6b7JjGa51-YOiLvKGavUbsAjEQpIOCdQ7cXcx8dOUlyDP5oU-knAi28U-mBfbiurFUv-laYOJY1UMqRIxRrVJKaZ4LwRIHm41d8w0yky0-bOEJPhBvK0mYmBBO86drYsXnOnY-stosIfCxS82D_q0ffJoijelXJoxNOMnJP8BAq-JhtQScfnroWZXf_ilZLCBmTkvl2va-D9x9SSNM8V7cfgQgdSWO31UmA0&state=CfDJ8OVuvnVG6_9Nphg79v1prru4BxrL9c3MKwcP1buvw6zjIE7TbEk3j76UQE4WHJ2YcodUwMoe0oZwguXeJE_Xjg0WSnq00A2RoBUya2ZEGkiug92j8GhTZwrnMkWdRT6aD0tuKJbOa0_DYFcY07ol4pfxmMYswsyZumW1Z_cCHpi4ZW5yzZm4x7NZll_fCS2DJktUa9rIn-c2nhp4pn3CLuY1TnzzedHQEqQkGY3zpEgsbXXCWFVQB_Hb722FacJfgg", host: "example.com", referrer: "https://example.com/"