AuthorizeAttribute with Roles not working when migrating from MVC to Endpoint Routing in ASP.NET Core 3.1

六月ゝ 毕业季﹏ 提交于 2020-12-10 07:42:51

问题


I'm trying to upgrade my project from .UseMVC (asp.net core 2.2 compat style) to .UseEndpoint Routing and I'm getting re-directed to my suthentication failed page for all my requests. It has to do with the Claims - If I remove the role part of [Authorize(Roles = "Admin")] to simply [Authorize] then it works. It seems that it isn't picking up the claims that are assigned to the user.

It seems to be a very similar issue as AuthorizeAttribute not working with Endpoint Routing in ASP.NET Core 3.1

The following paragraph is an excerpt from the linked post but modified to reflect my version of the issue

Everything worked fine in 2.2, but after migrating to 3.1 and enabling Endpoint Routing, this controller began to refuse requests to any endpoint when [Authorize(Roles = "Admin")] attribute is present. When I remove "Roles =" part and look at User.Claims, I can see that it does have the required claims/roles. This happens only if Endpoint Routing is enabled, in case of using UseMvc everything works properly. What's wrong with Authorization in Endpoint Routing mode?

Excerpt from 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"});
 });

回答1:


It turns out since we were using app.Use() middleware to fill in the user's roles from the DB, it needed to be called before UseAuthorisation so that the roles were loaded before authorisation was performed. (Like @CamiloTerevinto's comment)

 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();
 


来源:https://stackoverflow.com/questions/65028989/authorizeattribute-with-roles-not-working-when-migrating-from-mvc-to-endpoint-ro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!