Fork me on GitHub

Detail on HippoAuthenticationProvider (and HippoUserDetailsService) component

Introduction

This page will explain (a) how HippoAuthenticationProvider authenticates a user against Hippo Repository security data store, (b) how HippoUserDetailsServiceImpl assigns roles for the authenticated user.

Also see API Javadoc for details or customizations.

How to authenticate a user?

It is really simple! HippoAuthenticationProvider simply tries to invoke on javax.jcr.Repository#login(Credentials) by converting username and UsernamePasswordAuthenticationToken instance to SimpleCredentials instance.

If the login is sucessful, then the user should be authenticated. Otherwise, the authentication should fail.

See HippoAuthenticationProvider for detail.

How to assign roles to an authenticated user?

It is a bit complex. HippoUserDetailsServiceImpl simply executes the following JCR query first to find all the assigned group names:

//element(*, hipposys:group)[(@hipposys:members = '${username}' or @hipposys:members = '*')
and @hipposys:securityprovider = 'internal'];
        

Note: the ${username} is replaced by the real username at runtime.

Afterward, HippoUserDetailsServiceImpl executes a JCR query like the following example again to find all the hipposys:authrole nodes under /hippo:configuration/hippo:domains.

//hippo:configuration/hippo:domains/${domainName}/element(*, hipposys:authrole)
[ @hipposys:users = '${username}' or @hipposys:groups = 'author' or @hipposys:groups = 'editor' ... ]
        

Note: the ${domainName} is replaced by the property, roleDomainName ('everywhere' by default), and the ${username} is replaced by the real username at runtime, and the parts after 'or @hipposys:groups = ' are appended at runtime based on all the group names which were found in the previous step. So, for example, if the domainName is 'everywhere', the username is 'jdoe' and the user is in both 'author' and 'editor' groups, then the JCR query to execute should be like the following:

//hippo:configuration/hippo:domains/everywhere/element(*, hipposys:authrole)
[ @hipposys:users = 'jdoe' or @hipposys:groups = 'author' or @hipposys:groups = 'editor' ]
        

Next, in each hipposys:authrole node under the specified domain node (/hippo:configuration/hippo:domains/everywhere/ by default), HippoUserDetailsServiceImpl reads hipposys:role property.

A role name will be the concatenation of the role prefix property ('ROLE_' by default) and the hipposys:role property value.

For example, suppose the JCR query above resulted in:

  • /hippo:configuration/hippo:domains/everywhere/hippo:authrole
      - hipposys:role = "editor"
  • /hippo:configuration/hippo:domains/everywhere/hippo:authrole
      - hipposys:role = "admin"

Then, the end result of role names in HippoUserDetailsServiceImpl will be like the following set by default:

[ "ROLE_editor", "ROLE_admin" ]