ASP.NET Core 中的 Facebook、Google 和外部提供程序身份验证

作者:Valeriy NovytskyyRick Anderson

本教程演示如何生成 ASP.NET Core 应用,该应用可让用户使用外部身份验证提供程序提供的凭据通过 OAuth 2.0 登录。

以下几节中介绍了 FacebookTwitterGoogleMicrosoft 提供程序,这些提供程序使用本文中创建的初学者项目。 第三方程序包中提供了其他提供程序,例如 AspNet.Security.OAuth.ProvidersAspNet.Security.OpenId.Providers

让用户使用其现有凭据登录的好处:

  • 方便用户操作。
  • 将管理登录流程的许多复杂性转移到了第三方。

创建新的 ASP.NET Core 项目

  • 选择“ASP.NET Core Web 应用”模板。 选择“确定”
  • 在“身份验证类型”输入中,选择“个人帐户”。

应用迁移

  • 运行应用并选择“注册”链接
  • 输入新帐户的电子邮件地址和密码,再选择“注册”
  • 按照说明操作来应用迁移。

使用代理或负载均衡器转发请求信息

如果应用部署在代理服务器或负载均衡器后面,则可能会将某些原始请求信息转发到请求标头中的应用。 此信息通常包括安全请求方案 (https)、主机和客户端 IP 地址。 应用不会自动读取这些请求标头以发现和使用原始请求信息。

方案用于通过外部提供程序影响身份验证流的链接生成。 丢失安全方案 (https) 会导致应用生成不正确且不安全的重定向 URL。

使用转发标头中间件以使应用可以使用原始请求信息来进行请求处理。

有关详细信息,请参阅配置 ASP.NET Core 以使用代理服务器和负载均衡器

使用 SecretManager 存储登录提供程序分配的令牌

社交登录提供程序在注册过程中分配“应用程序 ID”和“应用程序机密”。 确切的令牌名称因提供程序而异。 这些令牌代表应用用来访问其 API 的凭据。 令牌构成“用户机密”,可利用机密管理器将其链接到应用配置。 用户机密是一种在配置文件(例如 )中存储令牌的更安全的替代方法appsettings.json

重要

机密管理器仅用于开发目的。 可使用 Azure Key Vault 配置提供程序存储和保护 Azure 测试和生产机密。

按照在 ASP.NET Core 中进行开发期间安全存储应用机密主题中的步骤进行操作,以便存储以下每个登录提供程序分配的令牌。

应用程序所需的安装登录提供程序

使用以下主题配置应用程序,以使用相应的提供程序:

多个身份验证提供程序

如果应用需要多个提供程序,请从 AddAuthentication 链接提供程序扩展方法:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApplication16.Data;

var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;

var connectionString = config.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options =>
                                 options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication()
   .AddGoogle(options =>
   {
       IConfigurationSection googleAuthNSection =
       config.GetSection("Authentication:Google");
       options.ClientId = googleAuthNSection["ClientId"];
       options.ClientSecret = googleAuthNSection["ClientSecret"];
   })
   .AddFacebook(options =>
   {
       IConfigurationSection FBAuthNSection =
       config.GetSection("Authentication:FB");
       options.ClientId = FBAuthNSection["ClientId"];
       options.ClientSecret = FBAuthNSection["ClientSecret"];
   })
   .AddMicrosoftAccount(microsoftOptions =>
   {
       microsoftOptions.ClientId = config["Authentication:Microsoft:ClientId"];
       microsoftOptions.ClientSecret = config["Authentication:Microsoft:ClientSecret"];
   })
   .AddTwitter(twitterOptions =>
   {
       twitterOptions.ConsumerKey = config["Authentication:Twitter:ConsumerAPIKey"];
       twitterOptions.ConsumerSecret = config["Authentication:Twitter:ConsumerSecret"];
       twitterOptions.RetrieveUserDetails = true;
   });

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

选择性地设置密码

使用外部登录提供程序注册,即表明还没有向应用注册密码。 这可让用户无需创建和记住站点密码,但也会使用户依赖外部登录提供程序。 如果外部登录提供程序不可用,则无法登录网站。

使用外部提供程序在登录过程中设置的电子邮箱创建密码和登录:

  • 选择右上角的“Hello <电子邮件别名>”链接,导航到“管理”视图

Web application Manage view

  • 选择 创建

Set your password page

  • 设置一个有效密码,可以用此密码和邮箱登录。

其他信息