问题描述
我有一个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构造函数中明确指定身份验证架构的授权,该授权将尝试使用所有可用的身份验证架构进行授权?
我为什么要这样做?
...因为我不想特定于控制器中的任何身份验证架构。我想要一个简单的基于角色的授权,并且不希望控制器授权代码依赖于除角色名称以外的任何其他内容。
解决方法
如何实现不明确指定身份验证 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