我有一个工作项目,需要使用Google和Microsoft帐户登录。到目前为止,它在本地主机上都可以正常工作,但是SignInManager<IdentityUser>.ExternalLoginSignInAsync
在服务器上部署时,两者均以相同的方式失败。用户可以像通过外部登录对话框一样工作,但是在回调中失败。
SignInResult
除了“失败”外没有提供其他说明。请注意,这是我第一次使用ASP.Net Core,因此,如果我错过了重要的事情,我不会感到惊讶。该网站不使用自动生成的登录页面。
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.Configure<IISOptions>(options =>
{
options.ForwardClientCertificate = false;
});
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication().AddGoogle(options =>
{
options.ClientId = Configuration["Authentication:Google:ClientId"];
options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
});
services.AddAuthentication().AddMicrosoftAccount(options =>
{
options.ClientId = Configuration["Authentication:Microsoft:ClientId"];
options.ClientSecret = Configuration["Authentication:Microsoft:ClientSecret"];
});
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(SqlConfigurationDatabase.Credentials));
services.AddDefaultIdentity<IdentityUser>().AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(name: "add", template: "{controller=Product}/{action=Add}");
});
}
}
编辑:我忘记了其余的登录代码。至于标记:
<form asp-controller="Home" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" target="_blank" class="form-horizontal">
@{
foreach (var provider in await SignInManager.GetExternalAuthenticationSchemesAsync())
{
var name = provider.DisplayName + ".png";
<button type="submit" name="provider" value="@provider.DisplayName" title="Log in using your @provider.DisplayName account">
<img src="~/images/@name" />
@provider.DisplayName
</button>
}
}
</form>
Home控制器是唯一与外部登录服务对话的控制器。
public class HomeController : Controller
{
private readonly UserManager<IdentityUser> users;
private readonly SignInManager<IdentityUser> signIn;
public HomeController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
{
users = userManager;
signIn = signInManager;
}
public IActionResult Index()
{
if (signIn.IsSignedIn(User))
return RedirectToLocal("/Product/Abc123");
return View();
}
public IActionResult Gdpr()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult ExternalLogin(string provider, string returnUrl = null)
{
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Home", new { ReturnUrl = returnUrl });
var properties = signIn.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
if (remoteError != null)
{
ModelState.AddModelError("", $"Error from external provider: {remoteError}");
return RedirectToAction(nameof(HomeController.Index), "Home");
}
var info = await signIn.GetExternalLoginInfoAsync();
if (info == null)
return RedirectToLocal(returnUrl);
var result = await signIn.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
if (result.Succeeded)
return RedirectToLocal(returnUrl);
else
return RedirectToLocal(returnUrl);
}
private IActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
return Redirect(returnUrl);
else
return RedirectToAction(nameof(HomeController.Index), "Home");
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout()
{
await signIn.SignOutAsync();
return RedirectToAction(nameof(HomeController.Index), "Home");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
目前没有负载平衡,群集,Web场或任何其他奇特的东西发生。我基本上只是调整了Visual Studio(ASP.NET Core 2.1 Web应用程序,其身份验证设置为单个用户帐户)创建的示例站点。