ASP.NET Core 3.1에서 MVC에서 끝점 라우팅으로 마이그레이션 할 때 역할이있는 AuthorizeAttribute가 작동하지 않음

Nov 26 2020

내 프로젝트를 .UseMVC (asp.net 코어 2.2 호환 스타일)에서 .UseEndpoint Routing으로 업그레이드하려고하는데 모든 요청에 ​​대해 내 의심 실패 페이지로 리디렉션됩니다. 클레임과 관련이 있습니다. [Authorize (Roles = "Admin")]의 역할 부분을 간단히 [Authorize]로 제거하면 작동합니다. 사용자에게 할당 된 클레임을 선택하지 않는 것 같습니다.

AuthorizeAttribute가 ASP.NET Core 3.1에서 끝점 라우팅과 함께 작동하지 않는 것과 매우 유사한 문제인 것 같습니다.

다음 단락은 링크 된 게시물에서 발췌 한 것이지만 문제의 내 버전을 반영하도록 수정되었습니다.

2.2에서는 모든 것이 잘 작동했지만 3.1로 마이그레이션하고 엔드 포인트 라우팅을 활성화 한 후이 컨트롤러는 [Authorize (Roles = "Admin")] 속성이있을 때 엔드 포인트에 대한 요청을 거부하기 시작했습니다. "Roles ="부분을 제거하고 User.Claims를 보면 필수 클레임 / 역할이 있음을 알 수 있습니다. 이는 엔드 포인트 라우팅이 활성화 된 경우에만 발생하며 UseMvc를 사용하는 경우 모든 것이 제대로 작동합니다. 엔드 포인트 라우팅 모드에서 인증에 어떤 문제가 있습니까?

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

답변

2 akraines Nov 29 2020 at 16:00

DB에서 사용자의 역할을 채우기 위해 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();