Limit Access to Documents for Site Visitors

Important note when using the walkthroughs

When the walkthroughs refer to some yaml configuration, in general, it is meant that you import this yaml into a locally running repository via the Console with auto-export enabled. If however you copy some yaml blob directly into your idea without auto-export, you have to uncomment the following lines if present in the yaml:

#.meta:category: system
#.meta:add-new-system-values: true

The reason for this is that the auto-export for some properties knows implicitly to add this meta info, however the yaml import in the Console does not support .meta lines. Thus, you have two options when following the walkthroughs:

  1. Copy the yaml snippet as-is into the Console with auto-export running
  2. Copy the yaml snippet to your idea while uncommenting the commented meta info

Introduction

Goal

Limit access to documents to certain user groups by configuring authorization at document level.

Background

Bloomreach Experience Manager's delivery tier supports authorization at mount and sitemap item levels, as well as at individual document level using security domains.

This page provides a worked out example of an implementation project with authorization at document level.

Example

This example is based on a standard implementation project created from the Maven archetype, with the Blog feature added.

The requirements this example implements are defined as follows:

  • Users can be a customer or staff member.
  • Some Blog documents can only be accessed by visitor allowed to read staff or customer labeled blogs.
  • Blog Documents with access level customer can only be accessed by customers and staff members.
  • Blog Documents with access level staff can only be accessed by staff members.

The approach to implement the requirements is:

Prepare the Project

Create a project using the Bloomreach Experience Manager Maven archetype.

Build and run the project.

In Essentials, add the Blog feature to the project.

Rebuild and restart the project.

In the Console, select the node /hst:myproject/hst:configurations/hst:default/hst:sitemap/login and change the property hst:scheme from https to http. This configures the login page in the website to use HTTP instead of HTTPS in your local development environment (don't do this in production environments!).

Add an Access Level Field to the Blog Document Type

You are going to use the Selections feature to define the different access levels in a value list and make the access level selectable in the Blog document type.

In the CMS, create a subfolder inside 'myproject' called 'value lists'. Inside it, create a new Value List document called 'access levels'.

Enter the following values:

Key Label
customer Customer
staff Staff

Save the value list document.

In Essentials, choose Tools, then Selections.

On the Document Types tab, add a new selection field to the Blog document type that enables authors to select the access level for a document:

  • Select the 'blogtype' document type.
  • Enter the name 'access level'.
  • Select the selection type 'multiple'.
  • Select presentation 'checkboxes'.
  • Select the value list 'access levels'.
  • Click 'Add new selection field'.

Exclude read access for unauthorized visitor

The first step is to make sure that for anonymous visitors, the Blog documents marked with access-level = staff or access-level = customer are not readable, and create security domains for authenticated visitors that can read customer blog documents and for visitors that can read staff and customer blog documents. For the anonymous visitors we need to constrain the default live-documents domain. At /hippo:configuration/hippo:domains/live-documents/hippo-document add :

/exclude-staff-docs:
  jcr:primaryType: hipposys:facetrule
  hipposys:equals: false
  hipposys:facet: myproject:accesslevel
  hipposys:filter: true
  hipposys:type: String
  hipposys:value: staff

and 

/exclude-customer-docs:
  jcr:primaryType: hipposys:facetrule
  hipposys:equals: false
  hipposys:facet: myproject:accesslevel
  hipposys:filter: true
  hipposys:type: String
  hipposys:value: customer

After the above addition the default HST liveuser is not allowed to read live documents any more that have 

myproject:accesslevel = staff

or

myproject:accesslevel = customer

Note that hipposys:filter: true  means that the constraint only applies if the property myproject:accesslevel is present!

Create security domain for staff and customer visitors

For the customer visitor domain, copy the /hippo:configuration/hippo:domains/live-documents to /hippo:configuration/hippo:domains/live-documents-customer, remove the /exclude-customer-docs node, and replace the readonly node with the following content:

/readonly:
  jcr:primaryType: hipposys:authrole
  hipposys:role: readonly
  hipposys:groups:
    #.meta:category: system
    #.meta:add-new-system-values: true
    type: string
    value: [customers]

For the staff visitor domain, copy the just created customer domain /hippo:configuration/hippo:domains/live-documents-customer to /hippo:configuration/hippo:domains/live-documents-staff, and remove the /exclude-staff-docs node, and replace the readonly node with the following content:

/readonly:
  jcr:primaryType: hipposys:authrole
  hipposys:role: readonly
  hipposys:groups:
    #.meta:category: system
    #.meta:add-new-system-values: true
    type: string
    value: [staff]

Now, we have a setup where the users in group customers can read blog documents with myproject:accesslevel = customer and users in group staff can read all blog documents and the default HST liveuser cannot read documents with  myproject:accesslevel = customer | staff

Create Customer and Staff Groups

Below /hippo:configuration/hippo:groups create two new groups

/customers:
  jcr:primaryType: hipposys:group
  hipposys:members:
    .meta:category: system
    .meta:add-new-system-values: true
    type: string
    value: []
  hipposys:securityprovider: internal
  hipposys:userroles: [xm.webfiles.reader]

and 

/staff:
  jcr:primaryType: hipposys:group
  hipposys:members:
    .meta:category: system
    .meta:add-new-system-values: true
    type: string
    value: []
  hipposys:securityprovider: internal
  hipposys:userroles: [xm.webfiles.reader]

Create new users and assign them to the group customers or staff. Make sure that you do not add existing CMS users to these groups since the CMS users have too much read access for being a frontend user! The CMS users namely can also read preview versions of a document. If you want the CMS users to be able to login into the websites (as we do for the current website you are looking at), you need to make use of specialized session pools (session pool for staff-liveuser and for customer-liveuser where after authenticating the user, the rendering gets delegated to either the staff-liveruser or customer-liveuser. This is explained in  https://developers.bloomreach.com/blog/2017/custom-session-pools---a-case-study.html and is in general a much better approach, though more complex to setup)

Protect Individual Documents

You are going to set access levels for individual Simple Content documents.

In the CMS, create some Simple Content documents inside the myproject/blogs folder and set their access level to customer, staff, or both.

Save and publish the documents.

Create a login

Setup a login functionality using JAAS login described at Delivery Tier Authentication Configuration.

Note that the below example renders the website with the JCR Session of the authenticated user (hst:subjectbasedsession : true), however if many logged in users have the same group of nodes they are allowed to read and the site is a high-traffic site, then it is better to use custom session pools instead, see https://developers.bloomreach.com/blog/2017/custom-session-pools---a-case-study.html

Configure Authorization using Logged-In User's Session

You are going to define the delivery tier to use the session of the logged-in user to perform authorization.

In the Console, select the node /hst:myproject/hst:hosts/dev-localhost/localhost/hst:root and set the following two properties to true:

/hst:myproject/hst:hosts/dev-localhost/localhost/hst:root:
  hst:sessionstateful: true
  hst:subjectbasedsession: true

This configures the delivery tier to perform authorization using the session of the logged-in user instead of the standard liveuser. As mentioned above, this has a performance penalty and has the downside that the authenticated user cannot also be a CMS user since a CMS user has too much read access (and can for example read preview and live document variants). So you'll need to maintain special users for logging in into the site. A much better approach is the custom session pools feature, but is more complex to setup.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?