Fork me on GitHub

Detail on HippoRepositoryRealm

Introduction

This page will explain (a) how HippoRepositoryRealm authenticates a user against Hippo Repository security data store, (b) how it finds roles and (c) how it assigns permissions for the authenticated user.

Also see Javadoc of HippoRepositoryRealm for details or customizations.

How to authenticate a user?

It is really simple! HippoRepositoryRealm simply tries to invoke on javax.jcr.Repository#login(Credentials) by converting UsernamePasswordToken instance to SimpleCredentials instance.

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

See #doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken) for detail.

How to assign roles to an authenticated user?

This one is also very simple! HippoRepositoryRealm simply executes the following JCR query by default 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 extracted from UsernamePasswordToken instance.

How to assign permissions to an authenticated user?

It is a bit more complex than the previous ones. Basically, HippoRepositoryRealm executes a JCR query like the following example to find all the hipposys:authrole nodes under /hippo:configuration/hippo:domains.

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

Note: the ${username} is replaced by the real username extracted from UsernamePasswordToken instance, and the parts after 'or @hipposys:groups = ' are appended at runtime based on all the role names which were found in the previous step. So, for example, if 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//element(*, hipposys:authrole)
[ @hipposys:users = 'jdoe' or @hipposys:groups = 'author' or @hipposys:groups = 'editor' ]
        

Next, in each hipposys:authrole node under a domain node (e.g, 'everywhere', 'hippodocuments', etc. under /hippo:configuration/hippo:domains/), HippoRepositoryRealm reads hipposys:role property.

A permission will be a concatenation of the domain node name, ':', and hipposys:role property value by default.

For example, suppose the JCR query above resulted in:

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

Then, the end result of permissions in HippoRepositoryRealm will be like the following set:

[ "workflow:readonly", "hippodocuments:editor", "everywhere:admin" ]
        

Note: Please see Understanding Permissions in Apache Shiro for detail on how the permission strings work.