从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用
Posted
技术标签:
【中文标题】从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用【英文标题】:AuthorizeAttribute with Roles not working when migrating from MVC to Endpoint Routing in ASP.NET Core 3.1 【发布时间】:2021-03-09 17:50:52 【问题描述】:我正在尝试将我的项目从 .UseMVC(asp.net 核心 2.2 兼容样式)升级到 .UseEndpoint Routing,并且对于我的所有请求,我都被重定向到我的身份验证失败页面。它与声明有关 - 如果我删除 [Authorize(Roles = "Admin")] 的角色部分以简单地 [Authorize] 则它可以工作。它似乎没有提取分配给用户的声明。
这似乎是一个与AuthorizeAttribute not working with Endpoint Routing in ASP.NET Core 3.1非常相似的问题
以下段落摘自链接帖子但经过修改以反映我的问题版本
在 2.2 中一切正常,但在迁移到 3.1 并启用后 端点路由,这个控制器开始拒绝任何请求 [Authorize(Roles = "Admin")] 属性存在时的端点。 当我删除 “Roles =”部分并查看User.Claims,我可以看到它确实有 所需的声明/角色。有时候是这样的 仅在启用端点路由时,在使用 UseMvc 的情况下 一切正常。 Endpoint 中的授权有什么问题 路由模式?
摘自 Startup.cs
app.UseSession();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseResponseCompression();
//Add the users Roles as claims to his identity so that it is picked up for authentication purposes
app.Use((context, next) =>
var userId = context.User.Identity.Name;
if (userId == null)
return next();
...
var roles = resourceDataAccess.GetRolesForUser(userId);
if (roles != null)
var claims = roles.Select(role => new Claim(ClaimTypes.Role, role.RoleEnum.ToString())).ToList();
var appIdentity = new ClaimsIdentity(claims);
context.User.AddIdentity(appIdentity);
return next();
);
app.UseEndpoints(endpoints =>
endpoints.MapHub<AppHub>("api/apphub");
endpoints.MapControllerRoute("default", "api/controller=Account/action=SignIn/id?");
endpoints.MapControllerRoute("catch-all", "api/*url",
new controller = "Utility", action = "NotFoundPage");
);
【问题讨论】:
这是一个很长的镜头,但您可以尝试将UseAuthorization
放在您的角色映射器中间件之后吗?
你可以按照这个说明使用中间件***.com/questions/56320523/…
该链接是关于创建策略的。我们要做的是使用内置的基于角色的身份验证。出于某种原因,它不尊重我们提供和分配给用户的角色。
@CamiloTerevinto - 你的回答解决了这个问题。 UseAuthentication 需要在映射代码之前,UseAuthorization 需要在之后。
【参考方案1】:
事实证明,由于我们使用 app.Use() 中间件从数据库中填充用户角色,因此需要在 UseAuthorisation 之前调用它,以便在执行授权之前加载角色。 (喜欢@CamiloTerevinto 的评论)
app.UseSession();
app.UseRouting();
app.UseAuthentication();
//Add the users Roles as claims to his identity so that it is picked up for authentication purposes
app.Use((context, next) =>
...
//Setup the authorisation middleware to run only after we have loaded the users roles.
app.UseAuthorization();
app.UseResponseCompression();
【讨论】:
很高兴听到您可以解决问题。鉴于 UseXXX 的顺序是调用代码的顺序,这对我来说似乎不正确以上是关于从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
从 ASP.NET Core 1.1 MVC 迁移到 2.0 后,自定义 cookie 身份验证不起作用
如何先用asp.net身份框架数据库将asp.net mvc迁移到asp.net core
从 2.2 迁移到 3.1 的 ASP.Net Core 解决方案在发布时不会运行
在 ASP.NET Core MVC6 中将文件和模型发布到控制器