Я использую Visual Studio Professional 2019 с Asp. Net Core 3.1 на Windows 10 Enterprise.
Я создаю веб-сайт, который отображает различные виды на основе аутентификации пользователь: если пользователь аутентифицируется с помощью своих учетных данных Active Directory, он может видеть больше вещей на веб-страницах, в противном случае он может видеть основную информацию c.
Так что я объединил использование аутентификации Windows и анонимной аутентификации установив оба на ИСТИНА в launchSetting. json:
{
"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.cs html):
@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, а затем я смогу увидеть все нужные данные на страницах.
Я попытался настроить Startup.cs для IIS Express и веб-серверы Kestel и запуск веб-сайта с использованием обоих: в настройках кнопки воспроизведения в 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?}");
});
}
}
Кестель
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:
Настройка Windows Аутентификация
Простая авторизация