我正在Windows 10 Enterprise上将Visual Studio Professional 2019与Asp.Net Core 3.1一起使用。
我正在建立一个基于用户身份验证显示不同视图的网站:如果用户使用其Active Directory凭据进行身份验证,那么他可以在网页上看到更多内容,否则他可以看到基本信息。
所以我在launchSetting.json中将Windows身份验证和匿名身份验证设置的使用都合并为TRUE:
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:50548",
"sslPort": 44312
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Name_Of_The_Project": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}
在控制器中,我创建了Login方法:
// GET: /Config/Login
public IActionResult Login()
{
Console.WriteLine("I'm in Login (GET)");
Console.WriteLine("----------------------------------");
return View();
}
它向我返回此视图(Login.cshtml):
@if (User.Identity.IsAuthenticated)
{
<h3>You are logged in</h3>
}
else
{
<h3>Please insert your Windows credentials to login</h3>
<div>Click the link and a window will appear</div>
<br />
<a href="/Config/LoginWindows">Login</a>
}
我在视图中使用“ User.Identity.IsAuthenticated”来检查用户是否已通过身份验证,以向他们显示正确的信息。因此,在这种情况下,如果用户未通过身份验证,则会显示一个按钮,该按钮将由控制器中的此方法处理:
[Authorize]
// GET: /Config/LoginWindows
public IActionResult LoginWindows()
{
Console.WriteLine("I'm in LoginWindows (GET)");
Console.WriteLine("----------------------------------");
return RedirectToAction("Login");
}
因为它具有[Authorize]属性,所以它触发Windows身份验证提示,我必须在其中输入凭据。如果正确,则将User.Identity.IsAuthenticated设置为TRUE,然后我可以在页面中看到所有正确的内容。
我尝试同时为IIS Express和Kestel Web服务器配置Startup.cs,并使用它们两者启动网站:在Visual Studio中播放按钮的选项中,如果我选择IIS Express,则将使用IIS Express代理;如果我选择Name_Of_The_Project,则将直接使用Kestel。
IIS Express
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// IIS/IIS Express
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/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.UseHttpsRedirection();
app.UseStatusCodePagesWithReExecute("/Config/LoginFailed"); // first asks me the credentials then if it fails, i'm redirected to the other page
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Kestel
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// KESTREL
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/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.UseHttpsRedirection();
app.UseStatusCodePagesWithReExecute("/Config/LoginFailed"); // first asks me the credentials then if it fails, i'm redirected to the other page
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
问题
我的问题是,在两种配置中,只有Microsoft Edge才具有正确的行为:单击登录页面中的按钮,出现提示,输入凭据,重新加载页面以表明我已登录。
在Google Chrome浏览器中,我单击“登录”页面中的按钮,它会自动对我进行身份验证,而不会显示任何提示。经过一段时间浏览网站后,User.Identity.IsAuthenticated返回FALSE,因此我需要再次单击登录按钮。
在Firefox中,提示会出现,但它不接受我的凭据,因此提示会每次重新加载,直到网页显示我没有访问权限为止。
我已遵循Microsoft文档:
即Internet选项>安全>受信任的站点添加您的网站url示例:http://localhost:6000或http://foo.bar.web:7000