在 ASP.NET Core 中使用 WS 联合身份验证对用户进行身份验证
本教程演示如何使用户能够使用 WS 联合身份验证提供程序登录,例如 Active Directory 联合身份验证服务 (ADFS) 或 Microsoft Entra ID。 它使用 Facebook、Google 和外部提供程序身份验证中描述的 ASP.NET Core 示例应用。
对于 ASP.NET Core 应用,WS 联合身份验证支持由 Microsoft.AspNetCore.Authentication.WsFederation 提供。 此组件从 Microsoft.Owin.Security.WsFederation 移植而来,并共享该组件的许多机制。 但是,这两个组件在几个重要方面有所不同。
默认情况下,新的中间件:
- 不允许未经请求的登录。 WS 联合身份验证协议的此功能容易受到 XSRF 攻击。 但是,可以使用
AllowUnsolicitedLogins
选项启用此功能。 - 不检查每个表单发布中的登录消息。 仅检查对
CallbackPath
的登录请求。CallbackPath
默认为/signin-wsfed
,但可以通过 WsFederationOptions 类的继承 RemoteAuthenticationOptions.CallbackPath 属性进行更改。 通过启用 SkipUnrecognizedRequests 选项,可以与其他身份验证提供程序共享此路径。
将应用注册到 Active Directory
Active Directory 联合身份验证服务
- 从 ADFS 管理控制台打开服务器的“添加信赖方信任向导”:
- 选择手动输入数据:
输入信赖方的显示名称。 该名称对 ASP.NET Core 应用并不重要。
Microsoft.AspNetCore.Authentication.WsFederation 不支持令牌加密,因此不要配置令牌加密证书:
- 使用应用 URL 启用对 WS 联合身份验证被动协议的支持。 验证应用的端口是否正确:
注意
端口必须是 HTTPS URL。 在开发期间托管应用时,IIS Express 可以提供自签名证书。 Kestrel 需要手动配置证书。 有关更多详细信息,请参阅 Kestrel 文档。
在向导的其余部分中单击“下一步”,最后单击“关闭”。
ASP.NET Core Identity 需要“名称 ID”声明。 从“编辑声明规则”对话框添加一个:
- 在“添加转换声明规则向导”中,保留默认模板“以声明方式发送 LDAP 属性”的选中状态,然后单击“下一步”。 添加将 SAM-Account-Name LDAP 属性映射到“名称 ID”传出声明的规则:
- 在“编辑声明规则”窗口中单击“完成”>“确定”。
Microsoft Entra ID
- 导航到 Microsoft Entra ID 租户的“应用注册”边栏选项卡。 单击“新建应用程序注册”:
- 输入应用注册的名称。 该名称对 ASP.NET Core 应用并不重要。
- 输入应用侦听的 URL 作为“登录 URL”:
- 单击“终结点”并记下联合元数据文档 URL。 这是 WS 联合身份验证中间件的
MetadataAddress
:
- 导航到新的应用注册。 单击“公开 API”。 单击“应用程序 ID URI”>“设置”>“保存”。 记下应用程序 ID URI。 这是 WS 联合身份验证中间件的
Wtrealm
:
在没有 ASP.NET Core Identity 的情况下使用 WS 联合身份验证
可以在没有 Identity 的情况下使用 WS 联合身份验证中间件。 例如:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(options =>
{
options.Wtrealm = Configuration["wsfed:realm"];
options.MetadataAddress = Configuration["wsfed:metadata"];
})
.AddCookie();
services.AddControllersWithViews();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(options =>
{
options.Wtrealm = Configuration["wsfed:realm"];
options.MetadataAddress = Configuration["wsfed:metadata"];
})
.AddCookie();
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?}");
});
}
添加 WS 联合身份验证作为 ASP.NET Core Identity 的外部登录提供程序
- 将 Microsoft.AspNetCore.Authentication.WsFederation 上的依赖项添加到项目中。
- 将 WS 联合身份验证添加到
Startup.ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication()
.AddWsFederation(options =>
{
// MetadataAddress represents the Active Directory instance used to authenticate users.
options.MetadataAddress = "https://<ADFS FQDN or AAD tenant>/FederationMetadata/2007-06/FederationMetadata.xml";
// Wtrealm is the app's identifier in the Active Directory instance.
// For ADFS, use the relying party's identifier, its WS-Federation Passive protocol URL:
options.Wtrealm = "https://localhost:44307/";
// For AAD, use the Application ID URI from the app registration's Overview blade:
options.Wtrealm = "api://bbd35166-7c13-49f3-8041-9551f2847b69";
});
services.AddControllersWithViews();
services.AddRazorPages();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication()
.AddWsFederation(options =>
{
// MetadataAddress represents the Active Directory instance used to authenticate users.
options.MetadataAddress = "https://<ADFS FQDN or AAD tenant>/FederationMetadata/2007-06/FederationMetadata.xml";
// Wtrealm is the app's identifier in the Active Directory instance.
// For ADFS, use the relying party's identifier, its WS-Federation Passive protocol URL:
options.Wtrealm = "https://localhost:44307/";
// For AAD, use the Application ID URI from the app registration's Overview blade:
options.Wtrealm = "api://bbd35166-7c13-49f3-8041-9551f2847b69";
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
AddAuthentication(IServiceCollection, String) 重载设置 DefaultScheme 属性。 通过 AddAuthentication(IServiceCollection, Action<AuthenticationOptions>) 重载可配置身份验证选项,这些选项可用于为不同的目的设置默认身份验证方案。 对 AddAuthentication
的后续调用会替代之前配置的 AuthenticationOptions 属性。
注册身份验证处理程序的 AuthenticationBuilder 扩展方法只能在每个身份验证方案中调用一次。 存在允许配置方案属性、方案名称和显示名称的重载。
使用 WS 联合身份验证登录
浏览到应用并单击导航标头中的“登录”链接。 有一个使用 WsFederation 登录的选项:
使用 ADFS 作为提供程序时,该按钮会重定向到 ADFS 登录页面:
使用 Microsoft Entra ID 作为提供程序,该按钮会重定向到 Microsoft Entra ID 登录页面:
新用户成功登录会重定向到应用的用户注册页面:
反馈
https://aka.ms/ContentUserFeedback。
即将推出:在整个 2024 年,我们将逐步取消以“GitHub 问题”作为内容的反馈机制,并将其替换为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈