Udostępnij za pośrednictwem


Prosta autoryzacja w ASP.NET Core

Autoryzacja w ASP.NET Core jest kontrolowana za pomocą atrybutu [Authorize] i jego różnych parametrów. W najbardziej podstawowej formie stosowanie atrybutu [Authorize] do kontrolera, akcji lub Razor strony ogranicza dostęp do tego składnika do uwierzytelnionych użytkowników.

Wymagania wstępne

W tym artykule założono, że masz podstawową wiedzę na temat ASP.NET Core Razor Pages i MVC. Jeśli dopiero zaczynasz ASP.NET Core, zobacz następujące zasoby:

Użyj atrybutu [Authorize]

Następujący kod ogranicza dostęp do AccountController uwierzytelnionych użytkowników:

[Authorize]
public class AccountController : Controller
{
    public ActionResult Login()
    {
    }

    public ActionResult Logout()
    {
    }
}

Jeśli chcesz zastosować autoryzację do akcji, a nie kontrolera, zastosuj AuthorizeAttribute atrybut do samej akcji:

public class AccountController : Controller
{
   public ActionResult Login()
   {
   }

   [Authorize]
   public ActionResult Logout()
   {
   }
}

Teraz tylko uwierzytelnieni użytkownicy mogą uzyskiwać dostęp do Logout funkcji.

Możesz również użyć atrybutu AllowAnonymous , aby zezwolić na dostęp nieuwierzytelnionemu użytkownikom do poszczególnych akcji. Na przykład:

[Authorize]
public class AccountController : Controller
{
    [AllowAnonymous]
    public ActionResult Login()
    {
    }

    public ActionResult Logout()
    {
    }
}

Pozwoliłoby to tylko uwierzytelnieni użytkownicy na AccountController, z wyjątkiem Login akcji, która jest dostępna dla wszystkich, niezależnie od ich uwierzytelnionego lub nieuwierzytelnionego/anonimowego stanu.

Ostrzeżenie

[AllowAnonymous] Pomija instrukcje autoryzacji. Jeśli połączysz [AllowAnonymous] i [Authorize] atrybut, [Authorize] atrybuty zostaną zignorowane. Na przykład w przypadku zastosowania [AllowAnonymous] na poziomie kontrolera:

  • Wszelkie wymagania dotyczące autoryzacji z [Authorize] atrybutów na tym samym kontrolerze lub metodach akcji na kontrolerze są ignorowane.
  • Oprogramowanie pośredniczące uwierzytelniania nie jest zwarciem, ale nie musi się powieść.

Następujący kod ogranicza dostęp do strony dla LogoutModelRazor uwierzytelnionych użytkowników:

[Authorize]
public class LogoutModel : PageModel
{
    public async Task OnGetAsync()
    {

    }

    public async Task<IActionResult> OnPostAsync()
    {

    }
}

Aby uzyskać informacje na temat globalnego wymagania uwierzytelnienia wszystkich użytkowników, zobacz Wymaganie uwierzytelnionych użytkowników.

Autoryzowanie atrybutu i Razor stron

Nie można zastosować ich AuthorizeAttribute do Razor programów obsługi stron. Na przykład [Authorize] nie można zastosować do OnGetprogramu , OnPostani żadnego innego programu obsługi stron. Rozważ użycie kontrolera MVC platformy ASP.NET Core dla stron z różnymi wymaganiami dotyczącymi autoryzacji dla różnych procedur obsługi. Używanie kontrolera MVC, gdy wymagane są różne wymagania dotyczące autoryzacji:

  • Jest to najmniej złożone podejście.
  • To podejście zalecane przez firmę Microsoft.

Jeśli zdecydujesz się nie używać kontrolera MVC, następujące dwa podejścia mogą służyć do stosowania autoryzacji do Razor metod obsługi strony:

  • Użyj oddzielnych stron dla procedur obsługi stron wymagających innej autoryzacji. Przenieś zawartość udostępnioną do co najmniej jednego widoku częściowego. Jeśli to możliwe, jest to zalecane podejście.

  • W przypadku zawartości, która musi współużytkować wspólną stronę, napisz filtr, który wykonuje autoryzację w ramach interfejsu IAsyncPageFilter.OnPageHandlerSelectionAsync. Projekt PageHandlerAuth w usłudze GitHub przedstawia następujące podejście:

    [TypeFilter(typeof(AuthorizeIndexPageHandlerFilter))]
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
    
        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }
    
        public void OnGet()
        {
    
        }
    
        public void OnPost()
        {
    
        }
    
        [AuthorizePageHandler]
        public void OnPostAuthorized()
        {
    
        }
    }
    
    public class AuthorizeIndexPageHandlerFilter : IAsyncPageFilter, IOrderedFilter
    {
        private readonly IAuthorizationPolicyProvider policyProvider;
        private readonly IPolicyEvaluator policyEvaluator;
    
        public AuthorizeIndexPageHandlerFilter(
            IAuthorizationPolicyProvider policyProvider,
            IPolicyEvaluator policyEvaluator)
        {
            this.policyProvider = policyProvider;
            this.policyEvaluator = policyEvaluator;
        }
    
        // Run late in the selection pipeline
        public int Order => 10000;
    
        public Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) => next();
    
        public async Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
        {
            var attribute = context.HandlerMethod?.MethodInfo?.GetCustomAttribute<AuthorizePageHandlerAttribute>();
            if (attribute is null)
            {
                return;
            }
    
            var policy = await AuthorizationPolicy.CombineAsync(policyProvider, new[] { attribute });
            if (policy is null)
            {
                return;
            }
    
            await AuthorizeAsync(context, policy);
        }
    
        #region AuthZ - do not change
        private async Task AuthorizeAsync(ActionContext actionContext, AuthorizationPolicy policy)
        {
            var httpContext = actionContext.HttpContext;
            var authenticateResult = await policyEvaluator.AuthenticateAsync(policy, httpContext);
            var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, httpContext, actionContext.ActionDescriptor);
            if (authorizeResult.Challenged)
            {
                if (policy.AuthenticationSchemes.Count > 0)
                {
                    foreach (var scheme in policy.AuthenticationSchemes)
                    {
                        await httpContext.ChallengeAsync(scheme);
                    }
                }
                else
                {
                    await httpContext.ChallengeAsync();
                }
    
                return;
            }
            else if (authorizeResult.Forbidden)
            {
                if (policy.AuthenticationSchemes.Count > 0)
                {
                    foreach (var scheme in policy.AuthenticationSchemes)
                    {
                        await httpContext.ForbidAsync(scheme);
                    }
                }
                else
                {
                    await httpContext.ForbidAsync();
                }
    
                return;
            }
        }
    

Ostrzeżenie

Przykładowe podejście PageHandlerAuth nie obejmuje następujących czynności:

  • Redaguj z atrybutami autoryzacji zastosowanymi do strony, modelu strony lub globalnie. Tworzenie atrybutów autoryzacji powoduje wielokrotne wykonywanie uwierzytelniania i autoryzacji, gdy do strony zastosowano również co najmniej jedno AuthorizeAttribute AuthorizeFilter wystąpienie.
  • Praca w połączeniu z rest systemem uwierzytelniania i autoryzacji ASP.NET Core. Należy sprawdzić, czy użycie tego podejścia działa poprawnie dla aplikacji.

W programach obsługi stron nie ma żadnych planów obsługi AuthorizeAttribute Razor .