我知道之前已经多次询问过这个问题,但遗憾的是不是关于ASP.NET核心网络应用程序,而是经典的ASP.NET网络应用程序。我在互联网上找到的所有答案都没有帮助我,因为ASP.NET核心应用程序的IIS配置与传统的ASP.NET有很大不同。例如,ASP.NET Core使用Kestrel代理,因此ASP.NET中的许多配置都不在ASP.NET Core中。我基本上已经尝试过我可能在互联网上找到的所有内容,但没有人帮助过我。我想它就像在IIS中的应用程序上启用匿名和Windows身份验证一样简单,就是这样,但我想它会比这更有用。
在单个asp.net核心Web应用程序中启用这两种身份验证的步骤是什么?
答案 0 :(得分:13)
IIS将充当反向代理,并负责设置并向Kestrel传输用户的Windows身份。首先,设置IIS以允许Windows和匿名身份验证:
然后,您需要更改web.config以要求IIS将Windows身份(如果找到一个)发送到您的ASP.NET Core应用程序,如下所示:https://stackoverflow.com/a/42163175/6827240
此时,如果使用“[Authorize]”属性创建控制器操作,HttpContext.User.Identity.Name;
应具有客户端使用的Windows标识的值。我回复了类似的内容:NTLM authentication on specific route in ASP.NET Core
好处是,如果您的客户端没有传递Windows身份令牌,标准控制器操作仍然有效,而受保护的(使用[Authorize]标签)将失败。
PS:我喜欢在详细模式下使用curl.exe来查看授权协议(协商协议,NTLM令牌......)中发生的事情。
答案 1 :(得分:4)
我对ASP.NET Core 2.0应用程序有类似的情况(除了单个控制器之外,在整个应用程序中使用Windows身份验证)并且Daboul的解释还不够。
我必须设置自here以来anonymous takes precedence所示的自定义中间件。
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");
}
}
及其在Startup.cs中的用法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseMiddleware<NtlmAndAnonymousSetupMiddleware>();
// other code here
}
因此,中间件仅接受对匿名控件的匿名请求,如果未提供Windows身份验证信息,则会提出质询。
由于中间件在匿名和需要身份验证之间存在差异,因此它看起来就像任何普通控制器一样:
[Route("Anonymous")]
public class AnonymousController : Controller
{
[HttpGet("Echo")]
public string Echo(string data)
{
return data;
}
}
(全部在Windows机器上完成)
Chrome +访问非匿名控制器操作=&gt;工作正常(@User.Identity.Name
和@Context.User.Identity.Name
都会返回正确的用户
Chrome +匿名操作=&gt;直接工作
Firefox(不直接从操作系统传输NTLM票证)+非匿名=&gt;模态请求user / pass =&gt;如果提供正确,它可以正常工作
Firefox +匿名操作=&gt;直接工作
答案 2 :(得分:2)
以防万一,我修改了@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;
}
}
然后修改public void Configure(IApplicationBuilder应用程序,IWebHostEnvironment env)
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<NtlmAndAnonymousSetupMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
答案 3 :(得分:0)
我有一个在IIS上禁用Windows身份验证的解决方案。您需要做的就是NTLM身份验证。只需将以下递归代码放入您的控制器登录操作中即可:
var result = await HttpContext.AuthenticateAsync(IISDefaults.AuthenticationScheme);
if (!result.Succeeded) {
await HttpContext.ChallengeAsync(IISDefaults.AuthenticationScheme); //performs NTLM handshake
return StatusCode(Response.StatusCode); // sends 401
}
// windows login has already succeed
// get user name and domain
WindowsIdentity winIdentity = (WindowsIdentity)result.Principal.Identity;
...等等