Dela via


Enkel auktorisering i ASP.NET Core

Auktorisering i ASP.NET Core styrs med [Authorize] attributet och dess olika parametrar. I sin mest grundläggande form begränsar tillämpningen av attributet till en kontrollant, åtgärd eller Razor sida åtkomsten till komponenten till autentiserade [Authorize] användare.

Förutsättningar

Den här artikeln förutsätter att du har en grundläggande förståelse för ASP.NET Core Razor Pages och MVC. Om du är nybörjare på ASP.NET Core kan du läsa följande resurser:

Använda attributet [Authorize]

Följande kod begränsar åtkomsten till autentiserade AccountController användare:

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

    public ActionResult Logout()
    {
    }
}

Om du vill använda auktorisering för en åtgärd i stället för kontrollanten AuthorizeAttribute tillämpar du attributet på själva åtgärden:

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

   [Authorize]
   public ActionResult Logout()
   {
   }
}

Nu kan endast autentiserade Logout användare komma åt funktionen.

Du kan också använda attributet för att tillåta åtkomst för icke-autentiserade AllowAnonymous användare till enskilda åtgärder. Till exempel:

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

    public ActionResult Logout()
    {
    }
}

Detta skulle endast tillåta autentiserade användare till AccountController, förutom åtgärden Login , som är tillgänglig för alla, oavsett deras autentiserade eller oautentiserade/anonyma status.

Varning

[AllowAnonymous] kringgår auktoriseringsinstruktioner. Om du kombinerar [AllowAnonymous] och ett [Authorize] attribut ignoreras attributen [Authorize] . Om du till exempel ansöker [AllowAnonymous] på kontrollantnivå:

  • Alla auktoriseringskrav från [Authorize] attribut på samma kontrollant eller åtgärdsmetoder på kontrollanten ignoreras.
  • Mellanprogrammet för autentisering är inte kortslutet men behöver inte lyckas.

Följande kod begränsar åtkomsten till sidan till autentiserade LogoutModelRazor användare:

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

    }

    public async Task<IActionResult> OnPostAsync()
    {

    }
}

Information om hur du globalt kräver att alla användare autentiseras finns i Kräv autentiserade användare.

Auktorisera attribut och Razor sidor

Det AuthorizeAttribute går inte att Razor tillämpa på sidhanterare. Det går till exempel [Authorize] inte att OnGettillämpa på , OnPosteller någon annan sidhanterare. Överväg att använda en ASP.NET Core MVC-styrenhet för sidor med olika auktoriseringskrav för olika hanterare. Använda en MVC-styrenhet när olika auktoriseringskrav krävs:

  • Är den minst komplexa metoden.
  • Rekommenderas av Microsoft.

Om du bestämmer dig för att inte använda en MVC-kontrollant kan följande två metoder användas för att tillämpa auktorisering på Razor sidhanterarmetoder:

  • Använd separata sidor för sidhanterare som kräver olika auktorisering. Flytta delat innehåll till en eller flera partiella vyer. När det är möjligt är detta den rekommenderade metoden.

  • För innehåll som måste dela en gemensam sida skriver du ett filter som utför auktorisering som en del av IAsyncPageFilter.OnPageHandlerSelectionAsync. GitHub-projektet PageHandlerAuth visar den här metoden:

    [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;
            }
        }
    

Varning

PageHandlerAuth-exempelmetoden gör inte följande:

  • Skriv med auktoriseringsattribut som tillämpas på sidan, sidmodellen eller globalt. Att skapa auktoriseringsattribut resulterar i att autentisering och auktorisering körs flera gånger när du har en till AuthorizeAttribute eller AuthorizeFilter instanser som också tillämpas på sidan.
  • Arbeta tillsammans med resten av ASP.NET Core-autentiserings- och auktoriseringssystemet. Du måste kontrollera att den här metoden fungerar korrekt för ditt program.

Det finns inga planer på att stödja AuthorizeAttribute sidhanterare Razor .