ASP.NET Core'da basit yetkilendirme

ASP.NET Core'daki yetkilendirme, özniteliği ve çeşitli parametreleriyle [Authorize] denetlenir. En temel biçiminde, özniteliği bir [Authorize] denetleyiciye, eyleme veya Razor Sayfaya uygulamak, bu bileşene erişimi kimliği doğrulanmış kullanıcılarla sınırlar.

Önkoşullar

Bu makalede, ASP.NET Temel Razor Sayfaları ve MVC hakkında temel bilgilere sahip olduğunuz varsayılır. ASP.NET Core'da yeniyseniz aşağıdaki kaynaklara bakın:

özniteliğini [Authorize] kullanma

Aşağıdaki kod, kimliği doğrulanmış kullanıcılara AccountController erişimi sınırlar:

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

    public ActionResult Logout()
    {
    }
}

Denetleyici yerine bir eyleme yetkilendirme uygulamak istiyorsanız, özniteliği eylemin AuthorizeAttribute kendisine uygulayın:

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

   [Authorize]
   public ActionResult Logout()
   {
   }
}

Artık işleve yalnızca kimliği doğrulanmış kullanıcılar erişebilir Logout .

Kimliği doğrulanmamış kullanıcıların tek tek eylemlere erişmesine izin vermek için özniteliğini de kullanabilirsiniz AllowAnonymous . Örneğin:

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

    public ActionResult Logout()
    {
    }
}

Bu, kimliği doğrulanmış veya kimliği doğrulanmamış/anonim durumlarına bakılmaksızın herkes tarafından erişilebilen eylem dışında Login yalnızca kimliği doğrulanmış kullanıcılara AccountControllerizin verir.

Uyarı

[AllowAnonymous] yetkilendirme deyimlerini atlar. ve özniteliğini birleştirirseniz [AllowAnonymous][Authorize] , [Authorize] öznitelikler yoksayılır. Örneğin, denetleyici düzeyinde uygularsanız [AllowAnonymous] :

  • Aynı denetleyicideki özniteliklerden veya denetleyicideki eylem yöntemlerinden [Authorize] gelen yetkilendirme gereksinimleri yoksayılır.
  • Kimlik doğrulama ara yazılımı kısa devreli değildir ancak başarılı olması gerekmez.

Aşağıdaki kod, Sayfaya LogoutModelRazor erişimi kimliği doğrulanmış kullanıcılarla sınırlar:

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

    }

    public async Task<IActionResult> OnPostAsync()
    {

    }
}

Genel olarak tüm kullanıcıların kimliğinin doğrulanmış olmasını gerektirme hakkında bilgi için bkz . Kimliği doğrulanmış kullanıcılar gerektirme.

Özniteliği ve Razor Sayfaları yetkilendirme

, Sayfa işleyicilerine Razor uygulanamıyor.AuthorizeAttribute Örneğin, [Authorize] , OnPostveya başka bir sayfa işleyicisine OnGetuygulanamaz. Farklı işleyiciler için farklı yetkilendirme gereksinimlerine sahip sayfalar için ASP.NET Core MVC denetleyicisi kullanmayı göz önünde bulundurun. Farklı yetkilendirme gereksinimleri gerektiğinde MVC denetleyicisi kullanma:

  • En az karmaşık yaklaşımdır.
  • Microsoft tarafından önerilen yaklaşımdır.

MVC denetleyicisi kullanmamaya karar verirseniz, Sayfa işleyici yöntemlerine yetkilendirme uygulamak için Razor aşağıdaki iki yaklaşım kullanılabilir:

  • Farklı yetkilendirme gerektiren sayfa işleyicileri için ayrı sayfalar kullanın. Paylaşılan içeriği bir veya daha fazla kısmi görünüme taşıyın. Mümkün olduğunda önerilen yaklaşım budur.

  • Ortak bir sayfayı paylaşması gereken içerik için, IAsyncPageFilter.OnPageHandlerSelectionAsync'in bir parçası olarak yetkilendirme gerçekleştiren bir filtre yazın. PageHandlerAuth GitHub projesi şu yaklaşımı gösterir:

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

Uyarı

PageHandlerAuth örnek yaklaşımı aşağıdakileri yapmaz:

  • Sayfaya, sayfa modeline veya genel olarak uygulanan yetkilendirme öznitelikleriyle oluşturma. Yetkilendirme özniteliklerini oluşturmak, sayfaya bir veya AuthorizeFilter daha fazla AuthorizeAttribute örneğin uygulandığında kimlik doğrulaması ve yetkilendirmenin birden çok kez yürütülmesine neden olur.
  • ASP.NET Core kimlik doğrulaması ve yetkilendirme sisteminin geri kalanıyla birlikte çalışın. Bu yaklaşımı kullanarak uygulamanız için doğru şekilde çalıştığını doğrulamanız gerekir.

Sayfa işleyicilerini desteklemeye AuthorizeAttributeRazor yönelik bir plan yoktur.