Authorization in ASP .NET Core Razor pages

Razor Pages doesn't support [Authorize] at the handler level. i.e. You can only authorise a page as a whole, on the PageModel itself, as noted in the docs:

Policies can not be applied at the Razor Page handler level, they must be applied to the Page.

If authorising the page as a whole isn't a workable solution, you might need to move your OnGetCreateAsync handler into a controller/action pair, which can be attributed with [Authorize] accordingly.

There's also a related GitHub issue in the docs for this:

The [Authorize] filter attribute has been supported since 2.0 in Razor Pages, but note that it works at the page model class level

If you need a better workaround, see akbar's answer and Jim Yabro's answer.


Another solution for it is to check authentication by if clause.like this:

if (!HttpContext.User.Identity.IsAuthenticated)
    {
      return Redirect("/Front/Index");
    }

and you can check roles in it too by finding role:

var user = await _userManager.FindByEmailAsync(model.Email);
var roles = await _userManager.GetRolesAsync(user);

I would recommend following Razor Pages authorization conventions in ASP.NET Core that looks like this:

services.AddRazorPages(options =>
{
    options.Conventions.AuthorizePage("/Contact");
    options.Conventions.AuthorizeFolder("/Private");
    options.Conventions.AllowAnonymousToPage("/Private/PublicPage");
    options.Conventions.AllowAnonymousToFolder("/Private/PublicPages");
});

In your case with policy test it would look like this:

options.Conventions.AuthorizePage("/Account", "test");

Source:

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/razor-pages-authorization?view=aspnetcore-5.0

Authorize attribute is supported but only on PageModel like this:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace PageFilter.Pages
{
    [Authorize]
    public class ModelWithAuthFilterModel : PageModel
    {
        public IActionResult OnGet() => Page();
    }
}

Source:

https://docs.microsoft.com/en-us/aspnet/core/razor-pages/filter?view=aspnetcore-5.0#authorize-filter-attribute


Don't use the AuthorizeAttribute since it's unsupported.

Instead, once you have configured your policies in Startup.cs, you will be able to check those policies from within the page handlers.

  1. Inject IAuthorizationService into your page model constructor
  2. Call AuthorizeAsync() from within the handler.
  3. Run a conditional check on the result's .Succeeded property.
  4. If .Succeeded is false, return a Forbid() result.

This has nearly the same result as the [Authorize(Policy=...)] but executes later in the page lifecycle.

using Microsoft.AspNetCore.Authorization;
// ...

public class TestPageModel : PageModel {
    readonly IAuthorizationService AuthorizationService;

    public TestPageModel(IAuthorizationService authorizationService) {
        AuthorizationService= authorizationService;
    }

    // Everyone can see this handler.
    public void OnGet() { }

    // Everyone can access this handler, but will be rejected after the check.
    public async Task<IActionResult> OnPostAsync() {
        
        // This is your policy you've defined in Startup.cs
        var policyCheck = await AuthorizationService.AuthorizeAsync(User, "test");

        // Check the result, and return a forbid result to the user if failed.
        if (!policyCheck.Succeeded) {
            return Forbid();
        }

        // ...

        return Page(); // Or RedirectToPage etc
    }
}