Hitachi Vantara Pentaho Community Wiki
Child pages
  • 05. Extending Security
Skip to end of metadata
Go to start of metadata

Useful Information

This document is relevant only to the Pentaho BI Platform version 1.2.0 or earlier. See the Pentaho BI Platform version 1.2.1 or later security documentation if you're using version 1.2.1 or later. (You can find the version you are running in several ways: (1) look at the log when the Pentaho BI Platform starts or (2) look at the bottom right of any page within the Pentaho BI Platform.)

The integration with Acegi Security was a key decision for the Pentaho Professional BI Platform. One of the driving reasons for this decision was its ability to integrate with CAS (for single sign-on), and the fact that the project has fairly widespread adoption.

However, the extensions that we've added may be either insufficient for your needs, or perhaps we haven't yet implemented the extensions to the provider you need to use. For example, we don't have extensions to the x509 populator yet, and we haven't yet implemented easier Microsoft Active Directory access (although it's technically possible to authenticate with Microsoft Active Directory and use it as a user details populator as long as the user depth isn't too deep).

For this, and for other reasons of extensibility, we have "interfaced" all of our security extensions to make it easy to provide your own implementations of the security extensions.

Interfaces

The following lists each of the interfaces that we have defined, and what they're used for. For the specific method signatures for each of the interfaces, please see the javadoc.

Interface

Description

com.pentaho.security.UserRoleListService

Defines functions for getting lists of users, roles, and role membership information.

com.pentaho.security.acls.IAclHolder

Defines functions for an access control list holder (an object having access control lists). These functions are for getting and setting the ACLs on a specific holder.

com.pentaho.security.acls.IAclPublisher

Defines the function for applying default ACLs during publish to the RDBMS repository.

com.pentaho.security.acls.IAclSolutionFile

Defines the function for insuring consistent parent-child navigation specifically for ACL resolution.

com.pentaho.security.acls.voter.IAclVoter

Defines the functions used to determine a users' access to a specific object, a users' status as a Pentaho administrator, and whether the user is granted a specific role.

Helper Classes

PentahoBasicAclVoter

To make implementation of ACL voters easy, the Pentaho Professional BI Platform has provided an abstract class for this purpose-- com.pentaho.security.acls.voter.AbstractPentahoAclVoter. This class reads the administrator role setting out of the pentaho.xml, and is the basis for the most natural extension point for ACL voting--the com.pentaho.security.acls.voter.PentahoBasicAclVoter. If you want to provide your own implementation of the IAclVoter interface, we recommend you consider starting with the PentahoBasicAclVoter. Use this class as your superclass, and override behaviors as desired.

SecurityUtils

Many of the functions that the ACL voter implementations rely on are provided in the com.pentaho.security.SecurityUtils class. Specifically, the getAuthentication method is extremely important because it's used to get the Acegi Security Authentication object that should be bound to the user's session. This method can be told to allow anonymous users, in which case it will return an Authentication object with the user named anonymous with only one granted role--ROLE_ANONYMOUS.

Voter Example

Let's say that you want to build your own ACL Voter. The requirements are as follows:

  • We allow anonymous users to access content.
  • However, if a user is specified in the access control list for an object, those access controls should override anything else in the access control list.

This is pretty much merging the functionality of the PentahoUserOverridesVoter and the PentahoAllowAnonymousAclVoter. So, where should we begin?

Well, there are several options. Here's what we could do:

  1. Subclass the AbstractPentahoAclVoter. This would require the most work because we'd have to duplicate the logic in the PentahoBasicAclVoter, the PentahoUserOverridesVoter and the PentahoAllowAnonymousAclVoter.
  2. Subclass the PentahoBasicAclVoter. This would be the second most difficult because this would require us to implement all the work currently being done by the PentahoUserOverridesVoter and the PentahoAllowAnonymousAclVoter.
  3. Subclass either the PentahoAllowAnonymousAclVoter or the PentahoUserOverridesVoter and add the functionality from the non-subclassed into the new one. This is the best route.

From the above analysis, we can see that #3 is the best way to go. But given this, how do we decide which way to go? Should we subclass the PentahoUserOverridesVoter or the PentahoAllowAnonymousAclVoter? Well, the javadoc for PentahoAllowAnonymousAclVoter states that it simply overrides the getAuthentication(IPentahoSession) method to allow anonymous sessions. And, since getting the authentication from the IPentahoSession object is actually a SecurityUtils call, this is the easiest functionality to add to any voter. However, the logic in the PentahoUserOverridesVoter is a bit more involved, and not something that we'd like to duplicate. So, what we will do is subclass the PentahoUserOverridesVoter, and simply add the getAuthentication(IPentahoSession) method that allows anonymous access. Here's what the class ends up looking like:

package com.pentaho.security.acls.voter;

import org.acegisecurity.Authentication;
import org.pentaho.core.session.IPentahoSession;

import com.pentaho.security.SecurityUtils;

public class PentahoUserOverridesAllowAnonymousAclVoter 
   extends PentahoUserOverridesVoter {
  // Allow anonymous users to have possible acls on an entry.
  public Authentication getAuthentication(IPentahoSession session) {
    return SecurityUtils.getAuthentication(session, true);
  }
}

As you can see, this turns out to be the best of both worlds, and it meets the requirements without being too arduous to implement.

The sky is the limit with respect to implementing your own ACL voter. For example, consider the case of a user (Sally) going on vacation, and delegating her responsibilities to someone else (Joe). Often this means a difficult change request going through IS that temporarily assigns Joe all of the roles that Sally is a member of. This would allow Joe access to all the solutions and action sequences that Sally has access to. Then, when Sally comes back, you'd have to process another change request through IS that would set Joe's access back the way it was before Sally went on vacation.

Or, you could create an ACL voter that, in addition to looking at Joe's roles, also looks in a relational database or an XML file for role overrides based on the date. In this way, instead of having to go through the IS department to make these changes, you could have time-based voter overrides.

Implementing Your Own Authenticator

Mostly, this will be a pointer over to the Acegi Security documentation for how you implement their interfaces (extending AbstractUserDetailsAuthenticationProvider for example). However, it's important that when you implement your UserDetailsService, that you also provide an implementation of com.pentaho.security.UserRoleListService. This interface is required for the Pentaho Professional BI Platform administrative user interface for assigning access to action sequences and solutions. It's also a requirement for some of the security input parameters (listing all users, etc.)

Other Extension Topics

So, how should you proceed if you already have your own security scheme implemented within your container? You don't want to re-tool it to completely use Acegi Security.

Well, we can give a little guidance here, but we haven't tried working outside the complete framework. So, take these points with a grain of salt. A little trial and error may be required to get everything working properly.

But, the most basic requirement is to get a subclass of org.acegisecurity.providers.AbstractAuthenticationToken into the HttpSession before the Pentaho Security Startup Filter gets invoked. Additionally, you'll need to replace the HttpSessionContextIntegrationFilter with one of your own making that does the validation and updates the Principal in the HttpSession.

Finally, you'll have to make sure and implement the UserDetails interface along with the UserRoleListService interface and hook them up in the system. You can probably do this all within a single servlet filter. For hooking up the UserRoleListService implementation, you can use the following example. The first line instantiates a UserDetailsRoleListService. The second line sets your custom UserRoleListService implementation. And the final line hooks the service into the Pentaho Professional BI Platform.

UserDetailsRoleListService s = new UserDetailsRoleListService();
s.setUserRoleListService(myUserRoleListService);
ProPentahoSystem.setUserDetailsRoleListService(s);
  • No labels