---
title: Implementing page permission checks
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

Permissions and authentication requirements can be configured individually for specific pages or sections on Xperience websites. This page describes scenarios where developers need to consider page permissions when implementing the live site application. For general information about page permissions, see [Page-level permissions (ACLs)](https://docs.kentico.com/13/managing-users/configuring-permissions/configuring-page-permissions/page-level-permissions-acls.md).

The implementation requirements for page-level permissions primarily depend on the [routing scheme](https://docs.kentico.com/13/developing-websites/implementing-routing.md) of your website:

- [Content tree-based routing](https://docs.kentico.com/13/developing-websites/implementing-routing/content-tree-based-routing.md) – page permissions are automatically checked when displaying pages on the live site, based on the **Check page-level permissions** [setting](https://docs.kentico.com/13/configuring-xperience/managing-sites/configuring-settings-for-sites/settings-security-membership.md). However, you may need to implement filtering based on permissions or authentication requirements when [loading page data](https://docs.kentico.com/13/developing-websites/retrieving-content/displaying-page-content.md).
- [Custom routing using URL patterns](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md) – for page permissions to have an effect on your website, developers need to use the appropriate API when loading and displaying pages in the site's code.

## Filtering pages based on permissions

You can control which [users](https://docs.kentico.com/13/managing-users/user-registration-and-authentication/integrating-xperience-membership.md) and [roles](https://docs.kentico.com/13/managing-users/role-management.md) can view pages on the live site by configuring **Read** permissions for pages and extending the [DocumentQuery call](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api.md) that [retrieves page content](https://docs.kentico.com/13/developing-websites/retrieving-content/displaying-page-content.md) with the **CheckPermissions** method. The method ensures the retrieved collection only contains pages for which the current user has the _Read_ permission.

```csharp

var articles = new DocumentQuery<Article>()
                    .OnSite("MySite")
                    .Culture("en-us")
                    .Path("/Articles", PathTypeEnum.Children)
                    .CheckPermissions());

```

The retrieved pages are now filtered based on _Read_ permissions, so only the specified users can view the content on the live site.

**Note**: The _CheckPermissions_ method does NOT filter pages based on their authentication requirements (_Requires authentication_ flag).

## Checking authentication and authorization

The Xperience API allows developers to evaluate the authentication and authorization requirements of individual pages. You can access the security configuration for specific pages through instances of the **IPageSecurity** interface, which provides the following members:

- **UserMeetsAuthenticationRequirements** – method that returns _true_ if the page does not require authentication (is publicly available) or if the current user is already authenticated.
- **IsUserAuthorizedToAccess**– method that returns _true_ if the current user is authorized to access the secured page based on its permissions and the site's configuration (the _Check page-level permission&#x73;_&#x73;etting from the _Security & Membership_ category).
- **IsSecured** – _bool_ property that directly returns the status of the page's _Requires authentication_ flag (regardless of the site's other configuration and settings).

To get the _IPageSecurity_ instance for a page, use one of the following approaches (depending on your scenario and context):

- Call the **Retrieve** method of the **IPageSecurityRetriever** service, with the page's _TreeNode_ object as the parameter.
- Access the **Security** property of an **IPageDataContext** instance. The data context for the current page can be retrieved using the _IPageDataContextRetriever_ service (requires manual initialization of the [page data context](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md#initializing-the-page-data-context) for pages handled by custom routes based on page type URL patterns).
- Access the **Security** property of an **IPageViewModel** instance – available as the model in the views of pages handled by [basic content tree-based routing](https://docs.kentico.com/13/developing-websites/implementing-routing/content-tree-based-routing/setting-up-content-tree-based-routing.md).

### Examples

When displaying pages using a custom controller, you can call the _IPageSecurity_ API to evaluate the page authentication and authorization requirements configured in Xperience, and return a suitable response.

```csharp

using System.Net;
using System.Web.Mvc;

using Kentico.Content.Web.Mvc;

...

private readonly IPageDataContextRetriever dataContextRetriever;

public PageController(IPageDataContextRetriever dataContextRetriever)
{
    // Initializes an instance of the IPageDataContextRetriever service
    this.dataContextRetriever = dataContextRetriever;
}

public ActionResult Index()
{ 
    // Gets the page data context for the current page
    // Requires manual initialization of the page data context if using custom routes and page type URL patterns
    IPageDataContext<TreeNode> dataContext = dataContextRetriever.Retrieve<TreeNode>();

    // First evaluates whether the page requires the user to sign-in
    // If required, redirects to the site's sign-in page
    if (!dataContext.Security.UserMeetsAuthenticationRequirements())
    {       
        return new HttpUnauthorizedResult();
    }

    // Evaluates whether the current user's permissions are sufficient to access the page
    // If not authorized, returns an HTTP status 403 response
    if (!dataContext.Security.IsUserAuthorizedToAccess())
    {
        return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
    }

    // Displays the page when the current user meets all authentication and authorization requirements
    return View();
}

```

The _IPageSecurity_ API can also be useful when filtering retrieved pages based on security requirements. For example, when loading [navigation menu](https://docs.kentico.com/13/developing-websites/building-website-navigation.md) items, you may wish to filter out pages that require authentication for non-authenticated users.

```csharp

using System.Collections.Generic;

using Kentico.Content.Web.Mvc;

...

// Instances of services used to load pages and their security configuration (e.g., obtained via dependency injection)
private readonly IPageRetriever pageRetriever;
private readonly IPageSecurityRetriever securityRetriever;

...

// Retrieves a collection of pages, filtering out pages that require authentication if the current user is not signed in
IEnumerable<TreeNode> pages = pageRetriever.Retrieve<TreeNode>(query => query
                                 .Where(page => User.Identity.IsAuthenticated || !securityRetriever.Retrieve(page).IsSecured));


```
