【问题标题】:Can Anonymous and Integrated Authentication be used in parallel?可以并行使用匿名和集成身份验证吗?
【发布时间】:2021-05-01 01:44:08
【问题描述】:
我目前正在尝试在 IIS 10 中为我的 ASP.NET Core 5.0 Web 应用启用 Windows 集成身份验证。
集成身份验证的基本设置有据可查,并且相当容易实现。但是我的 Web-App 有一个 ApiController,其中包含一些我希望未经身份验证的用户能够使用的操作。
在this Microsoft documentation 中,它声明我可以在我的 IIS 网页上启用匿名身份验证和集成身份验证,然后在我的 MVC 控制器中使用[AllowAnonymous] 和[Authorize] 属性。
我在网上做了额外的研究,发现很多 SO 和其他论坛关于这个主题的讨论,其中大部分可以追溯到 2010 年左右,可能已经过时,而链接的文档是 2021 年的,因此应该更多-迄今为止。我发现的讨论线程和博客上的共识是这是不可能的。当我自己尝试时,我也得出结论,匿名身份验证总是优先于集成身份验证并完全取消它。
那么,这里的 MS 文档是错误的还是我遗漏了什么?
【问题讨论】:
标签:
asp.net-core
iis
windows-authentication
iis-10
【解决方案1】:
好的,我找到this question后才知道。
匿名和集成验证实际上可以一起使用。但是您必须在自己的代码中做一些工作。
您必须在 IIS 中启用这两种身份验证类型,这使得默认情况下每个请求都被视为匿名请求。然后,您在请求管道中注册一个中间件,该中间件在被调用的 Controller 和 Action 处查找 [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 中的文件。