Monday, December 12, 2016

Hyperion EPM: Some tricks of kerberos SSO configuration


Sometime ago, we configured our Hyperion EPM for kerberos authentication. There are many  documents,  blogs which contain step-by-step kerberos SSO authentication. But during configuration I faced several issues and problems that were not explained in manuals, therefore I'm going to clarify configuration details. (this valid for Hyperion EPM and weblogic 10.3.6)

1. Understanding of URL Policy conditions

During kerberos configuration you have to set up policies for URLs. It define access to the application URLs (for example /SmartViewProviders, /index.jsp  and /* ).  Every URL policies contains one or more policy condition:
But there are some features  which everyone have to know in weblogic configuration:
There are two runtime groups in weblogic
      everyone - This group contains all anonymous users and, because it contains the users group, all users who have been authenticated.
      users - This group contains all users who have been authenticated.
When user requests URL (for example /index.jsp), weblogic puts user in the everyone and check access for all policy conditions which not requires authentication. And condition policy order ignores, therefore if your conditions are not user or group condition user stays in everyone group and gets URL without kerberos request and it can't be authenticated in Hyperion EPM. 
For example: if you set only one URL policy /* for workspace which allow access to everyone or by IP (PC name), you will not be authenticated and Hyperion show you login window. It is very important part of weblogic kerberos configuration.
If you use policy conditions: user or group weblogic uses kerberos for authentications and gets user token and user info (username, users domain groups), than it compares user credentials with conditions and allows access or not. In this way SSO successfully works. 
Let's look at some examples
1. Example with anonymous condition

Behavior:  all requests from host hyperion_server are allowed, but SSO doesn't work, therefore user can't be authenticated in workspace.

2. Example with group conditions:

Behavior: URL access allowed for users from AD group, this will be resolved by kerberos SSO, therefore
user can be authenticated in workspace.

3. Example with both conditions:

Behavior: Order is not important, access for anonymous access checks first, than checks authorized access, these conditions allow access to everyone, but SSO doesn't works.

2. How to allow native user access when SSO configured

We had mandatory requirement in kerberos projects: native users must have access to Hyperion Planning.
We need make some additional configuration:
- Set workspace property Allow direct logon after SSO failure = Yes
- Split URL policy for WORKSPACE deployment
 /* - url must have only allow access to everyone condition
/index.jsp - url must have only group condition, to allow SSO

How to use it? 
When you enter workspace using SSO (without login page), you have to log out from workspace, and login page will be accessible. 

Good luck with SSO configuration!


Monday, August 1, 2016

How Substitution API works !?


This post devotes to Oracle Data Integrator substitution API.  I was inspired for writing this post by one community thread. At first sights it looks very simple, but all obvious answers doesn’t work. I tried to research how substitution API really works. There is a result of my researching and thinking.

How does substitution API works?

Substitution API simply replaces java code fragments by result of code execution. For example , if we want to get value of previous step log messages into the Variable value:
Before execution this step ODI calculates previous step message and inserts result of function call. You can read more there:

There are two types of substitution API functions:
1) functions which calculates at package “compile “ stage (before interface or package execution)
2) functions which calculates during step execution: for example  odiRef.getPrevStepLog(), this function know nothing about previous step result until step not  finished (successful or not). 

What’s about our simple code?  Why it doesn’t work?
   String t = "<%=odiRef.getFrom().replace((char)34,(char)20) %>”;
It has to replace double quotes on spaces in the source table name. But we have errors on “compilation” stage.
It is impossible to get such error, because our function has right syntax, and we don’t call snpRef.getObjectName. Then I’ve got it, may be ODI doesn’t call odiRef function? May be it replaces it by string and then only calculates value … I tried to dump  odiRef call into file.
PrintWriter writer = new PrintWriter("c:\\temp\\subst.txt", "UTF-8");
writer.close(); %>
Obviously we had to get source table in the subst.txt, but I got:
<?=snpRef.getObjectName("L", "%COL_PRF0TEST", "ORATEST", "W")?>
What is it??? It is a string which contains call of snpRef.getObjectName.  Now we know what happening and why we got error and we can reproduce compilation stages.
1. Stage - code precompilation
ODI replace odiRef.getFrom() by STRING  and we get new code row.
<?=snpRef.getObjectName("L", "%COL_PRF0TEST", "ORATEST", "W")?>”.replace((char)34,(char)20)
2. Stage - code compilation
ODI executes replace function and we get result row:
<?=snpRef.getObjectName( L , %COL_PRF0TEST ,  ORATEST ,  W )?>”.replace((char)34,(char)20)
3.Stage - code execution
ODI executes <?=snpRef.getObjectName(…)?> , but we have already removed all double quotes,  and therefore we get SYNTAX error on this stage!!!
Now we know reasons of this error, but how to solve it???


Solution goes from definition of substitution API, result is always string, we have to put replace function into the string and on the stage 2 we have to get this string:
<?=snpRef.getObjectName( L , %COL_PRF0TEST ,  ORATEST ,  W )?>.replace((char)34,(char)20)”

I used this trick : I replaced closed parent and tag “)?” with string with replace function
String t="<%
String replaceStr=").replace((char)34,(char)20)?";
String replacedString=odiRef.getFrom().replace(")?",replaceStr);

Final  Test

We solve our problem, but lets do final tests. I put this script in  KM task.
Script contains different method calls therefore we could see behavior of each method group.Lets try to generate scenario which contains interface with our KM. And what can we see??? File subst.txt was created during scenario generation. File contains next rows:

C1_C1, C2_C2
<?=snpRef.getInfo("DEST_USER_NAME") ?>
<?=snpRef.getCatalogName() ?>
<?=snpRef.getPrevStepLog("MESSAGE") ?>
<?=TESTsnpRef.getObjectName("L", "%COL_PRF0TEST", "ORATEST", "W")?>
We could see that only first method was returns end value on compilation stage, all other methods replaced by snpRef instance calls


Substitution API is not that we see) it makes many transformations before execution, odiRef instances executes only on compilation stage and than replaces by string with snpRef instance call.  Therefore we need to be careful  when using such tricks like in my post. 


All my researches were done with ODI and