AuthorizeAttribute:如何尝试所有可用的身份验证模式?

问题描述

我有一个ASP.NET Core 3.1 Web应用程序,该应用程序具有ASP.NET身份验证和针对交互式用户页面)的基于角色的授权

现在,我也在同一个ASP.NET Core 3.1应用程序中实现了一些API控制器

[ApiController]
public class ConnectController : ControllerBase {...

我意识到,承载令牌端点并不是开箱即用的,所以我使用OpenIddict成功实现了它,并且运行良好。

我想在角色中使用Authorize属性

这有效:

[HttpGet]
[Authorize(Roles = "test01",AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
//[Authorize(Roles = "test01")] // This is not working,why?
public ActionResult<string> Ping01(string message)
{ ...

[Authorize(Roles = "test01")]不起作用,我不明白为什么? 出于诊断目的,我检查了所有可用的身份验证模式,共有六个,并且显式命名为“ OpenIdDict.Validation.AspNetCore”位于六个(最后一个,请参见下面的调试器屏幕快照)。换句话说,我希望将来可以自由更改API身份验证方法和实现,而无需接触控制器。

问题

如何实现未在AuthorizeAttribute构造函数中明确指定身份验证架构的授权,该授权将尝试使用所有可用的身份验证架构进行授权?

我为什么要这样做?

...因为我不想特定于控制器中的任何身份验证架构。我想要一个简单的基于角色的授权,并且不希望控制器授权代码依赖于除角色名称以外的任何其他内容

enter image description here

解决方法

如何实现不明确指定身份验证 AuthorizeAttribute 构造函数中的架构授权将 尝试使用所有可用的身份验证架构进行授权?

如果您不想明确指定架构,则必须在 ConfigureServices 方法中创建一个默认策略,如下所示:

services.AddAuthorization(options =>
                {
                    options.DefaultPolicy = new AuthorizationPolicyBuilder()
                        .RequireAuthenticatedUser()
                        .AddAuthenticationSchemes(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)
                        .Build();
                });

所以现在当您使用 [Authorize] 时,将自动包含默认策略。

现在使用此属性,您将获得角色授权的用户:

[Authorize,Authorize(Roles="admin")]

你可能会问,为什么要使用 Authorize 属性两次?
可以在此处找到答案:https://github.com/dotnet/aspnetcore/issues/18954