在ASP.NET Core应用程序中启用Windows身份验证和匿名身份验证

ash*_*lon 14 c# authentication iis-8 kestrel-http-server asp.net-core

我知道之前已经多次询问过这个问题,但遗憾的是,不是关于ASP.NET核心网络应用程序,而是经典的ASP.NET网络应用程序.我在互联网上找到的所有答案都没有帮助我,因为ASP.NET核心应用程序的IIS配置与传统的ASP.NET有很大不同.例如,ASP.NET Core使用Kestrel代理,因此ASP.NET中的许多配置都不在ASP.NET Core中.我基本上已经尝试过我可能在互联网上找到的所有内容,但没有人帮助过我.我想它就像在IIS中的应用程序上启用匿名和Windows身份验证一样简单,就是这样,但我想它会比这更有用.

在单个asp.net核心Web应用程序中启用这些身份验证的过程是什么?

Dab*_*oul 21

IIS将充当反向代理,并将负责设置和向Kestrel传输用户的Windows身份.首先,设置IIS以允许Windows和匿名身份验证:

在此输入图像描述

然后,您需要更改web.config以要求IIS将Windows身份(如果找到一个)发送到您的ASP.NET Core应用程序,如下所示:https://stackoverflow.com/a/42163175/6827240

此时,如果使用"[Authorize]"属性创建控制器操作,HttpContext.User.Identity.Name;则应具有客户端使用的Windows标识的值.我在这里回复了类似的东西:ASP.NET Core中特定路由上的NTLM身份验证

好处是,如果您的客户端未传递Windows身份令牌,则标准控制器操作仍然有效,而受保护的(使用[Authorize]标记)将失败.

PS:我喜欢在详细模式下使用curl.exe来查看授权协议(协商协议,NTLM令牌......)的情况.


Ale*_*xei 6

对于ASP.NET Core 2.0应用程序,我有一个类似的情况(除了单个控制器外,整个应用程序都使用Windows身份验证),而Daboul的解释还不够。

由于匿名优先,因此我必须按此处所示设置自定义中间件。

中间件

public class NtlmAndAnonymousSetupMiddleware
{
    private readonly RequestDelegate next;

    public NtlmAndAnonymousSetupMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.User.Identity.IsAuthenticated || context.Request.Path.ToString().StartsWith("/Anonymous"))
        {
            await next(context);
            return;
        }

        await context.ChallengeAsync("Windows");
    }

}
Run Code Online (Sandbox Code Playgroud)

及其在Startup.cs中的用法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseMiddleware<NtlmAndAnonymousSetupMiddleware>();

    // other code here
}
Run Code Online (Sandbox Code Playgroud)

因此,中间件仅接受对AnonymousController的匿名请求,如果未提供Windows身份验证信息,则中间件将面临挑战。

匿名控制器

由于中间件在匿名和需要身份验证之间有所不同,因此看起来就像任何普通控制器一样:

[Route("Anonymous")]
public class AnonymousController : Controller
{
    [HttpGet("Echo")]
    public string Echo(string data)
    {
        return data;
    }
}
Run Code Online (Sandbox Code Playgroud)

测验

(均在Windows计算机上完成)

  1. 镀铬+访问非匿名控制器动作=>工作正常(包括@User.Identity.Name@Context.User.Identity.Name返回正确的用户

  2. Chrome +匿名操作=>可直接运行

  3. Firefox(不会直接从OS传输NTLM票证)+非匿名=>模式要求用户/通过=>如果提供正确,它可以正常工作

  4. Firefox +匿名操作=>直接起作用


Alb*_*lio 6

万一有人想知道,我修改了@Alexei 的答案,在 Netcore 3.X 中使用属性而不是请求路径

首先创建类并获取端点元数据

public class NtlmAndAnonymousSetupMiddleware
{
    private readonly RequestDelegate next;

    public NtlmAndAnonymousSetupMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {

        if (context.User.Identity.IsAuthenticated || HasAnonymousAttribute(context))
        {
            await next(context);
            return;
        }

        await context.ChallengeAsync("Windows");
    }

    private bool HasAnonymousAttribute(HttpContext context)
    {
        var endpoint = context.GetEndpoint();
        var retVal = (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null);

        return retVal;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后修改public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

        app.UseAuthentication();
        app.UseAuthorization();
        app.UseMiddleware<NtlmAndAnonymousSetupMiddleware>();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
            endpoints.MapControllers();
        });
Run Code Online (Sandbox Code Playgroud)