[Mondrian] Dynamic roles

van der Werf, Guy guy.vanderwerf at wirecard.com
Thu Jul 7 08:00:46 EDT 2011


Hi Gretchen,

I can confirm I use the standard mechanism for serving MDXConnections, so roles are created clean each time. BTW I debug in Eclipse/Tomcat, and for a first-time Java coder, the incite into Pentaho’s ways of working is fantastic… e.g. see how many connections/roles are made by Analyzer during normal “open cube, drag-drop” usage. Ouch!

Regarding the “grant(hierarchy, Access.NONE, null, null, null)” – I raised it with you as I saw the assert myself. It does work however. I’d be interested to know what grant is made by Mondrian when a schema-based hard-coded rule revokes access to a hierarchy as no rollup policy is required. Due to your comments, I have changed my call to:  grant(hierarchy, Access.NONE, null, null, RollupPolicy.HIDDEN). http://mondrian.pentaho.com/documentation/schema.php#Defining_roles gives an example. Perhaps a question for Julian…

I already do your “checks” routinely. By debugging, I also know precisely which grants/revokes are taking place, and in which order. Good idea though – thank you.

In case I could learn from it, I accept your offer of the SteelWheels example implementation. Send it directly if you prefer.

Guy.

From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On Behalf Of Gretchen Moran
Sent: Donnerstag, 7. Juli 2011 04:18
To: Mondrian developer mailing list
Subject: Re: [Mondrian] Dynamic roles

Hi Guy,

What you are trying to do at a glance seems very straight forward, and has been successfully implemented. Let me clarify some areas in the solution to possibly help root out your problem.

If you are using the Pentaho BI Server’s standard mechanism for serving up MDXConnections, the code you have should successfully set your custom role on the connection. The BI Server does not reuse these instances, so the grants you set are thus “clean” with each new connection, and you should not have to worry about resetting the role grants on the connection. However, if you are custom writing the code to ask for an MDXConnection instance, you may want to mimic what the BI Server does – use the connection to issue a query, then discard it. There is a class called the PentahoConnectionFactory to accomodate this use.

I see nothing inherently wrong in the description of the logic in your constructor. The line of code that you single out, however, may cause you grief – if you want to define a constraint (a grant or deny) on any members under a hierarchy, you must set that hierarchy’s access to CUSTOM. So unless you intended to restrict all access to the hierarchy and all of its members, the grant(hierarchy, Access.NONE, null, null, null) will be a problem. In either case, the fact that you are passing a NULL rollupPolicy (the last argument in the grant) may be hazardous – if you look a the original RoleImpl code, there is an assert that rollupPolicy != null. You can easily set that value using a constant value from the RollupPolicy enum:

    enum RollupPolicy {
        /**
         * The value of the cell is null if any of the children are
         * inaccessible.
         */
        HIDDEN,

        /**
         * The value of the cell is obtained by rolling up the values of
         * accessible children.
         */
        PARTIAL,

        /**
         * The value of the cell is obtained by rolling up the values of all
         * children.
         */
        FULL,
    }

Sadly, none of my observations directly correlate to your assertion that an unrestricted user remains restricted after a restricted user has issued a query. Am I correct to assume that these users are two different Pentaho BI Server authenticated sessions? What are the results if you access the cube with the unrestricted user first? I am very skeptical that the cache is your culprit, because the role grants operate one level above the cache, and modify the actual query that gets issued. My advice is to continue to examine the logic in your constructor for the root of the problem.

Some other obvious checks that I make when I am working with this kind of customization:


1.       The metadata related to the authenticated user is what I believe it should be – for me, this usually means interrogating and verifying a set of session variables – yours may be to verify you are getting the proper metadata that you are expecting from your DB.

2.       Double check the rules and ordering that govern member grants in a Mondrian role.. they are listed in the Mondrian documentation. The ordering of grants can be tricky, and has caused me problems. Many times I have statically defined what I thought were the appropriate grants, only to find out that what I was asking for in my grants did not resolve to what I would have expected.

And the very last option, I have a simple, simple reference example of this implementation if you cannot get it sorted out. It uses the Pentaho sample data and Steel Wheels schema to demonstrate the approach you describe here. Let me know if that may be of any value to you, and I will get it to you.

Hope something here helps,
Gretchen Moran
From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On Behalf Of van der Werf, Guy
Sent: Wednesday, July 06, 2011 4:24 AM
To: Mondrian developer mailing list
Subject: Re: [Mondrian] Dynamic roles

… Sorry – it helps if one clicks “paste” instead of “send” :)
I completed my email below.
Thanks
Guy

From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On Behalf Of van der Werf, Guy
Sent: Mittwoch, 6. Juli 2011 10:01
To: Mondrian developer mailing list
Subject: Re: [Mondrian] Dynamic roles

Hi Gretchen,

Important lines are:
*************
public class WirecardMdxConnection extends MDXConnection
protected void init(PropertyList properties) {
super.init(properties);
this.session = PentahoSessionHolder.getSession();
Authentication auth = SecurityHelper.getAuthentication(this.session, false);
GrantedAuthority[] platformRoles = auth.getAuthorities();
Connection connection = this.getConnection();
Role wr = new WirecardRole(connection.getSchema(), this.datasourceService, this.session);
                                                connection.setRole(wr);
                                                setRole(wr);

public class WirecardRole extends RoleImpl {
                public WirecardRole(Schema schema, IDatasourceService datasourceService, IPentahoSession session) {
                                super();
                                Cube[] cubes = schema.getCubes();
                                                Dimension[] dimensions = cube.getDimensions();
                                                                Hierarchy[] hierarchies = dimension.getHierarchies();
                                                                                Level[] levels = hierarchy.getLevels();
*************
The last 4 lines above check each cube, dim, hierarchy and level-members for authorization based on (cached) metadata from a DB. I make appropriate calls to:
grant(<cube|dim|hierarchy|level-members>, Access.NONE) OR grant(<cube|dim|hierarchy|level-members>, Access.ALL)

Only the constructor is overridden. I do not clone existing roles, and mine are mutable. I’m happy with all business logic.
Only 1 statement gives me concern as to whether the implementation is correct: grant(hierarchy, Access.NONE, null, null, null); Confirm that too if you can please.

Your time on this is appreciated.
Thanks,
Guy

From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On Behalf Of Gretchen Moran
Sent: Dienstag, 5. Juli 2011 19:51
To: Mondrian developer mailing list
Subject: Re: [Mondrian] Dynamic roles

Hi Guy,

Can you give any details on exactly what functionality in the role you are changing/extending (method overrides specifically)? We have implemented several versions of dynamic roles (specifically generating the grants/denies) with no caching issues, but the implementation has many nuances we’ve learned over time. We have descended both RoleImpl and the DelegatingRole with success.

Gretchen Moran
From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On Behalf Of van der Werf, Guy
Sent: Tuesday, July 05, 2011 10:47 AM
To: Mondrian developer mailing list
Subject: Re: [Mondrian] Dynamic roles

Hi Brian,
Thanks for that. If I wanted to just assign a different role *name* (as in ceo, dev etc) then this would be a possibility, but I’m creating a customized Mondrian role (class) which extends “RoleImpl”. I reference metadata in a DB based on user, schema and cube, and grant/revoke access to cubes, dims, hierarchies and members as required. Works, but caching is stuffed.
Guy

From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On Behalf Of Brian Hagan
Sent: Dienstag, 5. Juli 2011 15:57
To: Mondrian developer mailing list
Subject: Re: [Mondrian] Dynamic roles

Guy,

Instead of extending MDXConnection, you may want to consider using the MondrianUserSessionUserRoleListMapper (pentahoObjects.spring.xml) , which allows you to change the role of an authenticated user based upon a session variable. This technique does not require you to dynamically modify the schema. However, the role, which are you assigning to the user, must be defined in the schema. The trick is then getting the variable in the session.

Thanks,

Brian

From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On Behalf Of van der Werf, Guy
Sent: Tuesday, July 05, 2011 9:31 AM
To: Mondrian developer mailing list
Subject: [Mondrian] Dynamic roles

Hi all,

With reference to Jira BISERVER-4992, I would like ask a question regarding caching in Mondrian.

Using Pentaho 3.8, I’ve extended “MDXConnection” to allow setting a custom role (extends RoleImpl) that is configured depending on reference metadata held in an existing authorization data source. This works as planned, but caching is a problem, and I wondering if anyone could shed some light on possible caching strategies. I should add that I do not use a dynamic schema processor in this solution.

I have 1 solution so far. I switch schema cache off in the catalog, and set “UseSchemaPool=false” in “DataSourceInfo” in “datasources.xml”. To ensure the same cache behavior (i.e. effectively none) in schemas not in “datasources.xml”, I could set this in the connection properties too (but that’s not done yet). The result is: I have no useful caching and performance in dashboards is noticeably pathetic.

So… does anyone have experience in Mondrian caching when dynamically changing the role, but not the schema xml?

Thanks,
Guy

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.pentaho.org/pipermail/mondrian/attachments/20110707/c4e0ded2/attachment.html 


More information about the Mondrian mailing list