首页 > 解决方案 > .NET Core 中的 Windows 身份验证在 Chrome 中不显示提示

问题描述

我在 Windows 10 Enterprise 上使用 Visual Studio Professional 2019 和 Asp.Net Core 3.1。

我正在构建一个基于用户身份验证显示不同视图的网站:如果用户使用他的 Active Directory 凭据进行身份验证,那么他可以在网页上看到更多内容,否则他可以看到基本信息。

因此,我在launchSetting.json 中将Windows Authentication 和 Anonymouse Authentication 设置的使用结合为 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 快递

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 具有正确的行为:我单击登录页面中的按钮,出现提示,我输入了我的凭据,页面重新加载说我已登录。

在谷歌浏览器中,我单击登录页面中的按钮,它会自动对我进行身份验证而不显示任何提示。浏览网站一段时间后,User.Identity.IsAuthenticated 返回 FALSE,所以我需要再次单击登录按钮。

在 Firefox 中,会出现提示,但它不接受我的凭据,因此每次都会重新加载提示,直到网页显示我没有访问权限。

我已关注 Microsoft Docs:

配置 Windows 身份验证

简单授权

标签: c#authenticationasp.net-core.net-coreauthorization

解决方案


即互联网选项 > 安全 > 受信任的站点添加您的网站 URL 例如:http://localhost:6000http://foo.bar.web:7000


推荐阅读