Repository Session Security Delegation - BloomReach Experience - Open Source CMS

This article covers a Hippo CMS version 11. There's an updated version available that covers our most recent release.

18-01-2017

Repository Session Security Delegation

For better understanding of this page, you can first read  Repository Authorization and Permissions.

Security delegation provides the possibility to combine the access control rules of two JCR Sessions, optionally constrained with some custom extra rules.

Example Use Cases

A use case for Security Delegation is the requirement that a CMS editor that wants to preview the document he is working on should be able to see this document in the channel manager preview. However, the preview in the channel manager is rendered with the HST (site) previewuser which might not have read access to the document the CMS editor is working on. To make this possible, the preview in CMS for the editor should be rendered with:

[The documents the HST site previewuser can read] +
[The documents the CMS editor can read -/-
     The live and draft documents the CMS editor can read ]

See Channel Manager Preview with Security Delegation for the above example. 

Another use case for Security Delegation is when the live site contains a login where (CMS) visitors after authentication should see all the live documents the site liveuser is allowed to read + all the live documents the authenticated visitor is authorized to read. If however the JCR session belonging to the authenticated user can also read preview documents, these documents need to be excluded, since the visitor is viewing the live site. Thus:

[The documents the HST site liveuser can read] +
[The documents the CMS editor can read -/-
     The preview and draft documents the CMS editor can read]

Background general JCR Session Authorization and Permissions

To explain the security delegation concept, first a small graphical recap of Repository Authorization and Permissions regarding security domains, domain rules and facet rules. For simplicity, only readable vs unreadable JCR nodes are considered. Having write access to nodes in a certain domain is a matter of specifying a role with write access on a domain rule.

Security domains

A security domain defines a set of documents on which permissions (eg read, write) can be set for a group or user. A JCR Session has a set of security domains, with optionally different permissions per security domain. In the image below, a JCR Session that contain the three security domains can read the green nodes.

Domain rules

A security domain consists of one or more domain rules. Each domain rule consists of one or more facet rules. A document belongs to the security domain if it matches one or more of the domain rules and a document matches a domain rule if it matches all of the facet rules.

 

Repository Authorization and Security Delegation

For security delegation, it must be possible to combine the set of security domains of two sessions. The set of security domains that gives read access to nodes for a single JCR session are displayed below by the green circles. A security delegated JCR session can have the read access of both sessions combined.

Creating a security delegated session

To get hold of a security delegated session you can use HippoSession#createSecurityDelegate:

/**
* Create a new Session that contains the union of access control rules
* of this Session and the provided session, with the optional addition
* of custom domain rules.  Those rules will be added to existing domain
* rules, imposing additional restrictions on the session.
*/
Session createSecurityDelegate(Session session,
                               DomainRuleExtension... domainRuleExtensions)
                               throws RepositoryException; 

For combining the above two sessions without adding any optional restrictions, use:

public Session createSecurityDelegate(Session s1,
                                      Session s2)
                                      throws RepositoryException {
    Session securityDelegate = ((HippoSession)s1).createSecurityDelegate(s2);
    return securityDelegate;
}

The combined Session above will have read (write) access to all the nodes of session1 and session2 combined. Note that

(HippoSession)s1).createSecurityDelegate(s2);

is equivalent to

(HippoSession)s2).createSecurityDelegate(s1); 

Creating a security delegated session with extra restrictions

The example use case described above needs an extra option for the security delegation creation. The combined sessions need some extra restriction(s) to exclude, for example, preview and draft documents from one or both sessions.

 

The above is achieved by adding one or more extra domain rule extensions while creating the security delegate. What actually is added with a domain rule extension is a Facet Rule (the purple ellipses above in the graph at the Domain Rules) that gets applied to a specific Domain Rule ( or to every Domain Rule when using wildcards *) of the combined sessions. Since a document only matches a Domain Rule if and only if all Facet Rules match, you can narrow down the readable documents (nodes) as shown above. For this you need DomainRuleExtension api and FacetRule api shown below

Creating a security delegated session for the above two sessions adding the extra constraint that the nodetype must not be of type myproject:internaldocument to for example the domain rule hippo-document for the domain hippodocuments can be done as follows:

public Session createExcludeInternalDocs(Session session1,
                                         Session session2)
                                         throws RepositoryException {
    // The false is that nodetype must not be of type
    // myproject:internaldocument and true is for that the
    // FacetRule is optional or not, however does not have
    // impact on 'nodetype' facet rules
    FacetRule internalDocsRule = new FacetRule("nodetype",
                                               "myproject:internaldocument",
                                                false,
                                                true,
                                                PropertyType.NAME);
    // The internalDocsRule is applied to the domain
    // '/hippo:configuration/hippo:domains/hippodocuments' and then to the
    // domain rule hippo-document.
    DomainRuleExtension dre = new DomainRuleExtension("hippodocuments",
                                             "hippo-document",
                                             Arrays.asList(internalDocsRule));
    return ((HippoSession)session1).createSecurityDelegate(session2, dre);
}

The above has the disadvantage that you need to explicitly know the name of the domain and the domain rule to which the extra FacetRule should be applied. However, it is quite common you need a general FacetRule to be applied to any domain rule of the combined security delegated session. For example if you want access rights of the site previewuser to be combined with the cms editor, you want the add the constraint to the cms editor that documents should be in preview state. Applying a FacetRule to any domain and/or to any domain rule can be done by using wildards. For example:

public Session createOnlyPreviewDocs(Session previewUser,
                                     Session cmsUser)
                                     throws RepositoryException {
    // first true means that the property hippo:availability
    // must be equal to 'preview', and second true means
    // that the FacetRule only applies to documents that
    // have the property 'hippo:availability' : In other words
    // the FacetRule is optional.
    FacetRule previewDocsRule = new FacetRule("hippo:availability",
                                              "preview",
                                               true,
                                               true,
                                               PropertyType.STRING);
    // apply the domain rule extension to any domain * and within any domain
    // to any facet rule *.
    DomainRuleExtension dre = new DomainRuleExtension("*",
                                            "*",
                                            Arrays.asList(previewDocsRule));
    return ((HippoSession)previewUser).createSecurityDelegate(cmsUser, dre);
}

Since the #createSecurityDelegate is a varargs argument for DomainRuleExtenions combining the above createSecurityDelegateExcludeInternalDocs and createSecurityDelegatePreviewDocs is trivial. Just add both dre's to the #createSecurityDelegate method.

 

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?