匿名身份验证和集成身份验证可以并行使用吗?

时间:2021-01-27 08:36:37

标签: asp.net-core iis windows-authentication iis-10

我目前正在尝试为 IIS 10 中的 ASP.NET Core 5.0 Web 应用启用 Windows 集成身份验证。 集成身份验证的基本设置有据可查,并且相当容易实现。但是我的 Web 应用程序有一个 ApiController,其中包含一些我希望未经身份验证的用户能够使用的操作。

this Microsoft documentation 中,它指出我可以在我的 IIS 网页上启用匿名身份验证和集成身份验证,然后在我的 MVC 控制器中使用 [AllowAnonymous][Authorize] 属性。

我在网上做了额外的研究,发现很多 SO 和其他论坛关于这个主题的讨论,其中大部分可以追溯到 2010 年左右,可能已经过时,而链接的文档是 2021 年的,因此应该更多-迄今为止。我发现的讨论主题和博客的共识是这是不可能的。当我自己尝试时,我也得出结论,匿名身份验证始终优先于集成身份验证并完全取消它。

那么,这里的 MS 文档是错误的还是我遗漏了什么?

1 个答案:

答案 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 中的文件。