我目前正在尝试为 IIS 10 中的 ASP.NET Core 5.0 Web 应用启用 Windows 集成身份验证。 集成身份验证的基本设置有据可查,并且相当容易实现。但是我的 Web 应用程序有一个 ApiController,其中包含一些我希望未经身份验证的用户能够使用的操作。
在 this Microsoft documentation 中,它指出我可以在我的 IIS 网页上启用匿名身份验证和集成身份验证,然后在我的 MVC 控制器中使用 [AllowAnonymous]
和 [Authorize]
属性。
我在网上做了额外的研究,发现很多 SO 和其他论坛关于这个主题的讨论,其中大部分可以追溯到 2010 年左右,可能已经过时,而链接的文档是 2021 年的,因此应该更多-迄今为止。我发现的讨论主题和博客的共识是这是不可能的。当我自己尝试时,我也得出结论,匿名身份验证始终优先于集成身份验证并完全取消它。
那么,这里的 MS 文档是错误的还是我遗漏了什么?
答案 0 :(得分:0)
好的,我在找到 this question 后想通了。
匿名身份验证和集成身份验证实际上可以一起使用。但是你必须在你自己的代码中做一些工作。
您必须在 IIS 中启用这两种身份验证类型,这使得默认情况下每个请求都被视为匿名请求。然后,您在请求管道中注册一个中间件,该中间件在被调用的控制器和操作中查找 [Authorize]
属性。如果找到,则要求客户端提供 Windows 登录信息。只需确保您在请求管道中的 app.UseRouting();
之后和 app.UseAuthentication
/app.UseAuthorization
之前注册中间件。
这是我用于中间件的代码,希望对某人有帮助:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RProcessServiceCore.Code
{
public class SingleSignOnMiddleware
{
private readonly RequestDelegate next;
public SingleSignOnMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
if (!context.User.Identity.IsAuthenticated)
{
Endpoint endpoint = context.GetEndpoint();
if(endpoint != null)
{
foreach (var meta in context.GetEndpoint().Metadata)
{
if (meta is AuthorizeAttribute)
{
await context.ChallengeAsync("Windows");
return;
}
}
}
}
await next.Invoke(context);
}
}
}
如您所见,我使用 context.GetEndpoint().Metadata
。
这是各种元数据元素的集合,包括装饰被调用控制器和动作的属性。
因此,您可以在其中搜索类型为 AuthorizeAttribute
的对象。
这种方法实现了对所有用 [Authorize]
修饰的控制器和操作强制执行 Windows 身份验证,但允许对没有此属性的控制器和操作进行匿名请求。这种方法还允许匿名访问 wwwroot 中的文件。