asp.net-core - .Net Core Identity 外部登录不起作用
问题描述
我有一个为谷歌设置了外部登录的网站。我已经成功地让它在开发中工作,但是当我转向生产时,它却失败了。当我单击该按钮时,它并没有将我发送到 Google 的 account.google.com 页面,而是将我发送到/Identity/Account/ExternalLogins
错误代码为HTTP ERROR 400
. 生产和环境之间的按钮是相同的。除了电子邮件发送部分,一切都与脚手架期间生成的相同。我的生产环境使用 Ubuntu 和 Nginx。这可能是什么原因造成的?我无法在生产之外重现该问题。
顺便说一句,这是默认按钮:
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name"
title="Log in using your @provider.DisplayName account">@provider.DisplayName
</button>
</form>
我的按钮是更改的默认谷歌登录按钮,但它在开发中有效,所以我认为这并不重要:
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
<div class="g-signin2" style="border:inherit;" data-onsuccess="onSuccess" data-gapiscan="true" data-onload="true">
<div style="height:36px;width:120px;" class="abcRioButton abcRioButtonLightBlue">
<button class="abcRioButtonContentWrapper" style="border:inherit; background-color:white !important"
type="submit" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">
<img class="position-absolute" src="https://assets.stickpng.com/images/5847f9cbcef1014c0b5e48c8.png" style="left: 12px;height: 18px;bottom: 10px;">
<span style="font-size:13px;line-height:34px;" class="abcRioButtonContents">
<span class="ml-3">Sign in</span>
</span>
</button>
</div>
</div>
</form>
以下是我的相关部分,为简洁起见Startup.cs
,删除了一些内容ConfigureServices()
:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(Configuration.GetConnectionString("UserDB"), MySqlOptions => MySqlOptions
.ServerVersion(new Version(8, 0, 22), ServerType.MySql)));
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.User.RequireUniqueEmail = true;
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._";
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 8;
});
services.AddAuthentication()
.AddGoogle(options =>
{
IConfigurationSection googleAuthNSection =
Configuration.GetSection("Authentication:Google");
options.ClientId = googleAuthNSection["ClientId"];
options.ClientSecret = googleAuthNSection["ClientSecret"];
});
services.AddServerSideBlazor();
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<ApplicationUser>>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
ConnectionString = Configuration["ConnectionStrings:DataDB"];
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHeadElementServerPrerendering();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
经过更多调查并将日志记录设置为跟踪后,我发现了以下错误:
连接 ID“0HM5SB235ONN8”错误请求数据:“带有‘连接:升级’的请求不能在请求正文中包含内容。”
我认为是因为我的sites-enabled/default
文件,我必须根据官方 Blazor 部署文档以这种方式配置:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Connection $http_connection;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
解决方案
问题出在我的 nginx 文件中,我错误地将其设置为托管。我将其更改为以下内容并且有效:
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
server {
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html;
server_name domain.us;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
}
}
然后我改变了我Startup.cs
的包括:
if (string.Equals(
Environment.GetEnvironmentVariable("ASPNETCORE_FORWARDEDHEADERS_ENABLED"),
"true", StringComparison.OrdinalIgnoreCase))
{
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto;
// Only loopback proxies are allowed by default.
// Clear that restriction because forwarders are enabled by explicit
// configuration.
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
}
//#################
app.UseForwardedHeaders();
app.UseCookiePolicy(new CookiePolicyOptions(){
MinimumSameSitePolicy = SameSiteMode.Lax
});
app.UseCertificateForwarding();
推荐阅读
- c# - 缺少 Visual Studio“REST Api 客户端”
- c# - 'ComputeShader 不包含 SetMatrix 的定义'
- ml.net - ML.NET:用于 csv 加载的类型推断?
- sql - 使用 pandas.read_sql 查询带参数的数据库
- xpath - 量角器 subLocator 管道
- sql - 查找每个 product_id 的最新 change_date 的 new_price
- c - 如何将字符串作为C中线程的参数传递
- django - Django - 特定项目的基于类的视图
- java - 创建 CSV 文件 Android
- java - 如何使用 Android 从 Cloud Firestore 中的地图中检索特定字段?