Uploaded image for project: '[Read Only] - Hippo Site Toolkit 2'
  1. [Read Only] - Hippo Site Toolkit 2
  2. HSTTWO-4670

Provide a new and default configured RepositoryAuthenticationProvider based on user roles

    XMLWordPrintable

Details

    • Improvement
    • Status: Closed
    • Normal
    • Resolution: Fixed
    • None
    • 14.0.0
    • None
    • None

    Description

      The new RepositoryAuthenticationProvider is a replacement for the now deprecated JcrAuthenticationProvider and HippoAuthenticationProvider implementations (the latter used to be the default).

      Instead of querying and leveraging the brXM security model directly this provider makes use of the now standard feature of HippoSession.getUser().getUserRoles() and based on the configuration can map (some of) them to Role principals.

      To implement this more efficiently, the AuthenticationProvider interface is extended with method Set<Role> getRolesByUser(User user), with a default delegation to the now deprecated Set<Role> getRolesByUsername(String username) method.
      The RepositoryAuthenticationProvider implements this new method and thereby removes the need to (again) lookup the user data when provided the User object as was returned from the User authenticate(String userName, char [] password) method call. This User object (implementation class TransientUser) namely holds the (detachted) HippoSession SessionUser. 

      The configuration parameters thereafter used for filtering and mapping the SessionUser.getUserRoles() to Role principals are:

      • requiredUserRole(String): when not empty both the authenticate(String, char[]) and getRolesByUser(User) methods will check and require the user to have at least the specified userrole. Default: empty.
      • excludedUserRolePrefixes(String): a String of one or more prefixes (delimited by excludedUserRolePrefixesDelimiter(String)) to exclude the userroles which name starts with such prefix(es). When blank or null, no userrole name prefix exclusion will be applied. Default: empty.
      • excludedUserRolePrefixesDelimiter(String): the delimiter (string) to split the prefixes provided through excludedUserRolePrefixes(String). Default: "," (comma).
      • includedUserRolePrefix(String): the userrole name prefix required for all userroles to be included. When blank or null, all not-yet-excluded userroles will be included. Default: empty.
      • stripIncludedUserRolePrefix(boolean): when includedUserRolePrefix(String) is non-empty, strip that prefix from the included userroles when mapping to a Role. Default: true.
      • rolePrefix(String): When not empty all included userroles will be mapped to a Role with this prefix to their name. Default: empty.
      • defaultRoleName(String): When not empty, adds a predefined Role with this name to the Set<Roles> result from method getRolesByUser(User)

      The above configuration parameters all can be set through the following Spring bean (which will become the standard provided setup, later):

        <bean id="org.hippoecm.hst.security.AuthenticationProvider" class="org.hippoecm.hst.security.impl.RepositoryAuthenticationProvider">
          <meta key="org.hippoecm.hst.site.container.SpringComponentManager.registerCondition"
                value="config.containsKey('java.security.auth.login.config')" />
          <!-- System repository to retrieve roles for user. -->
          <constructor-arg index="0" ref="javax.jcr.Repository" />
          <!-- System repository credentials to retrieve roles for user. -->
          <constructor-arg index="1" ref="javax.jcr.Credentials.hstconfigreader" />
          <!-- User authentication repository against which each user will be authenticated. -->
          <constructor-arg index="2" ref="javax.jcr.Repository.delegating" />
          <property name="requiredUserRole" value="${security.authentication.required.userrole}" />
          <property name="excludedUserRolePrefixes" value="${security.authentication.excluded.userrole.prefixes}" />
          <property name="excludedUserRolePrefixesDelimiter" value="${security.authentication.excluded.userrole.prefixes.delimiter}" />
          <property name="includedUserRolePrefix" value="${security.authentication.included.userrole.prefix}" />
          <property name="stripIncludedUserRolePrefix" value="${security.authentication.strip.included.userrole.prefix}" />
          <property name="rolePrefix" value="${security.authentication.role.prefix}" />
          <!-- Default role to be provided always (if not already provided) -->
          <property name="defaultRoleName" value="${security.authentication.default.role}" />
        </bean>
      

      and the following default hst-config.properties:

      ### Hippo Login Module Authentication Provider configurations ###
      # optional required userrole to be allowed to be authenticated
      security.authentication.required.userrole = 
      # default excluded standard provided userroles (prefixed with xm-)
      security.authentication.excluded.userrole.prefixes = xm-
      # , delimiter separating multiple excluded userrole prefixes
      security.authentication.excluded.userrole.prefixes.delimiter= ,
      # default include only standard provided userroles (prefixed with xm-): effectively by default don't include any!
      security.authentication.included.userrole.prefix = 
      # by default strip the userrole prefix (if any) from the produced role name
      security.authentication.strip.included.userrole.prefix = true
      # prefix to be added to produced role names (default no prefix added)
      security.authentication.role.prefix =
      # default role to be added to anyone authenticated (if not already added): to be specified *without* possible role.prefix
      security.authentication.default.role = everybody
      

      The above default configuration effectively will map no userroles (both excluded and include prefix are by default "xm-"), but will always add/return default Role "everybody".

      Therefore to effectively make use of the role mapping (besides the authentication) feature, a project will need to customize/override a few of these configuration properties!

      Example usage

      In the hippo-testsuite project a (minimal) example setup is used with the following configuration overrides:

      security.authentication.required.userrole = hst-site-user
      security.authentication.included.userrole.prefix = site-
      

      This will require everybody logging in through a site to have at least the userrole hst-site-user assigned, and only will filter/map userroles of the authenticated user to role principals which userrole name starts with "site-"

      In the testsuite the following example configuration is used to set this up:

      definitions:
        config:
          /hippo:configuration/hippo:userroles:
            /hst-site-user:
              jcr:primaryType: hipposys:userrole
            /site-admin:
              jcr:primaryType: hipposys:userrole
            /xm-cms-user:
              hipposys:userroles:
                operation: add
                value: [hst-site-user]
          /hippo:configuration/hippo:users/admin:
            hipposys:userroles:
              operation: add
              value: [site-admin]
          /hippo:configuration/hippo:groups/admin:
            hipposys:userroles:
              operation: add
              value: [site-admin]
      

       The above yaml bootstrap configuration defines:

      • the hst-site-user and site-admin userroles
      • allows users with the  xm-cms-user userrole to authenticate through the site
      • the admin user and admin group users are given the site-admin userrole, which will be mapped to role principal admin

      Now, with the above setup, finally HST role security can be used and enforced, for example for access to a specific sitemap item like:

      definitions:
        config:
          /hst:hst/hst:configurations/demosite/hst:sitemap:
            jcr:primaryType: hst:sitemap
            /mashup:
              jcr:primaryType: hst:sitemapitem
              hst:authenticated: true
              hst:roles: [admin]
      

      The above example sitemap item /mashup will require authentication and only a user with the admin role principal (mapped from the site-admin userrole) will be allowed to access it.  

      Multi-site use-cases

      When a project uses multiple site modules (wars) using/needing separate hst security configuration (e.g. distinct sets of roles and/or required.userrole), each site module can use independent configuration overrides.
      For example to use and map distinct sets of userroles per site module, you can define and use a different required userrole like hst-siteA-user and hst-siteB-user, and distinct and mutably exclusive userrole prefixes like siteA- and siteB- to achieve this. 

      Attachments

        Activity

          People

            Unassigned Unassigned
            adouma Ate Douma
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: