Monday, January 30, 2012

OpenIDM - The Next Generation Identity Management Solution

Gael Allioux from ForgeRock visited us earlier this week during his APAC trip. We had a great OpenIDM workshop conducted here in Singapore.


I must say I'm impressed with the progress of OpenIDM v2.0. Yes, it still not mature and lack some features at the moment. But the Synchronization Engine is fully complete and I'm equally impressed OpenIDM v2.0 has already been deployed to production in some key customers' sites!







From an architecture perspective, OpenIDM v2.0 is clean.


That's it! Clean and lightweight. 

.


Wednesday, January 4, 2012

Policy Agent 2.2 in CDSSO mode connecting to OpenAM Issue

One of my customers has a legacy Policy Agent 2.2 configured in CDSSO mode. It needs to connect to the newly installed OpenAM 9.5.3 server.



No luck... It was not a breeze porting over... We kept getting the following error:
WARNING: LdapSPValidator.validateAndGetRestriction: Invalid agent ID: http://stqa.as.com.sg:80/

See here.


Finally after much research, I found a link from Oracle. Not exactly the same deployment, but similar sympton.

The Web Proxy Agent 2.2-01 in Cross Domain Single Sign-on mode does not work with Access Manager 7.1 Patch . The agentRootURL requirement was added as a security measure to ensure that CDC is handing off ssotoken cookie to trusted agents running at known URLs.


Workaround
  • Go to Access Control > / (Top Level Realm) > Agents > 2.2 Agents > UrlAccessAgent
  • Key in agentRootURL=http://stqa.as.com.sg:80/ to Agent Key Value(s).



Jackpot!


.

OpenAM: #403x error

Sometimes, when a Policy Agent is configured and this very not-so-helpful error #403x appears on the browser, one needs to investigate further...

Usually, I systematically scan through the following log files:
1. Agent debug log files (at node where PA is installed)
2. OpenAM debug log files (usually Authentication will reveal what's wrong)

In this particular case, the Policy Agent was not defined properly in OpenAM.

amCDC:01/04/2012 12:07:36:371 PM SGT: Thread[http-2020-4,5,main] WARNING: LdapSPValidator.validateAndGetRestriction: Invalid agent ID: http://stqa.as.com.sg:80/ amCDC:01/04/2012 12:07:36:371 PM SGT: Thread[http-2020-4,5,main] ERROR: Invalid Agent: Could not get agent for the realm java.lang.Exception: Invalid Agent: Not configured in directory at com.iplanet.services.cdc.LdapSPValidator.validateAndGetRestriction(LdapSPValidator.java:160) at com.iplanet.services.cdc.CDCServlet.redirectWithAuthNResponse(CDCServlet.java:394) at com.iplanet.services.cdc.CDCServlet.doGetPost(CDCServlet.java:355) at com.iplanet.services.cdc.CDCServlet.doGet(CDCServlet.java:270) at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at com.sun.identity.setup.AMSetupFilter.doFilter(AMSetupFilter.java:91) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:864) at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579) at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1665) at java.lang.Thread.run(Thread.java:662)

amCDC:01/04/2012 12:07:36:371 PM SGT: Thread[http-2020-4,5,main] ERROR: CDCServlet.doGetPost java.lang.Exception: Invalid Agent: Could not get agent for the realm at com.iplanet.services.cdc.LdapSPValidator.validateAndGetRestriction(LdapSPValidator.java:229) at com.iplanet.services.cdc.CDCServlet.redirectWithAuthNResponse(CDCServlet.java:394) at com.iplanet.services.cdc.CDCServlet.doGetPost(CDCServlet.java:355) at com.iplanet.services.cdc.CDCServlet.doGet(CDCServlet.java:270) at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at com.sun.identity.setup.AMSetupFilter.doFilter(AMSetupFilter.java:91) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:864) at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579) at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1665) at java.lang.Thread.run(Thread.java:662)


.

Wednesday, December 21, 2011

OpenDJ Replication Server error during handshake phase




I have a pair of OpenDJ servers running in MMR mode. Customer has a sudden requirement to change IP addresses.

Simple request.. So I went ahead to modify the /etc/hosts. As simple as that.

No. The following error is observed in OpenDJ errors logs on both nodes:

[21/Dec/2011:12:46:32 +0800] category=SYNC severity=SEVERE_ERROR msgID=14942387 msg=Replication server 30809 was attempting to connect to replication server a125.az.com/172.8.8.125:8888 but has disconnected in handshake phase


[21/Dec/2011:12:46:32 +0800] category=SYNC severity=SEVERE_ERROR msgID=14942263 msg=In Replication server Replication Server 8888 30809: replication servers 200.2.2.125:8888 and 172.8.8.125:8888 have the same ServerId : 20398

:
:

[21/Dec/2011:12:46:36 +0800] category=SYNC severity=SEVERE_ERROR msgID=14942316 msg=Unable to send monitor data request for domain "cn=admin data" to replication server RS(30809) due to the following error: Socket closed

I resolved this by restarting both nodes.


.

Tuesday, December 20, 2011

OpenAM Fedlet

A customer asked me what's a OpenAM Fedlet and its usage. 



There isn't a lot of detailed document on OpenAM Fedlet. But this article from Oracle is great!

ForgeRock's documentation only has a section on Using Fedlets in Java Web Applications.

In layman term, this is my interpretation of Fedlet:

Basically, big organizations with budget will be using OpenAM Federation service.

e.g. One organization will install OpenAM to act as IdP (Identity Provider), while the rest of the organizations will enable their applications to be SAMLv2 -ready. These applications will then act as SP (Service Provider).

However, this takes time and effort and money.

Smaller organizations will definitely not be able to overhaul their applications to be SAMLv2-ready, as it is not cost-effective. So the way to go is to just deploy Fedlets (generated from OpenAM servers).


The Fedlet will act like a bridge between the OpenAM server (acting as IdP) and the applications.


It's simple and neat.

.

Friday, December 9, 2011

Overriding OpenAM classes


I was trying to change some behavior in OpenAM core components and I find the easiest way to do it is:
  • Modify the OpenAM source code
  • Compile the Java class
  • Deploy the compiled class in ../WEB-INF/classes
  • Restart OpenAM

The application container will let /WEB-INF/classes take priority over the class in the jar file residing in the /WEB-INF/lib directory. Nice!

In fact, it's not recommended to put back the modified class into the original jar file. I find that ugly in practice.

.

Wednesday, November 30, 2011

APR based Apache Tomcat Native Library

I want better performance running OpenAM on Tomcat application server, thus I spent the effort to configure APR (Apache Portable Runtime) for Tomcat.

As usual (this is not my 1st time), I always encounter this error whenever I start Tomcat after configuration:

Nov 30, 2011 4:01:23 PM org.apache.catalina.core.AprLifecycleListener init



INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /am/bin/jdk1.6.0_27/jre/lib/amd64/server:/am/bin/jdk1.6.0_27/jre/lib/amd64:/am/bin/jdk1.6.0_27/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib

 
This is a very silly mistake for not following the instruction carefully.
 
The resolution is to add the following to catalina.sh:

[am@testMachine bin]$ vi catalina.sh


JAVA_OPTS="-server -Xms2048M -Xmx2048M -Djava.library.path=/usr/local/apr/lib"
 
 
.

Monday, November 14, 2011

Agent-less SSO

Sometimes, legacy or COTS (commerical off the shelf) web applications cannot be customized to integrate with Policy Agent. That's where ESSO comes into play (and that explains why ESSO solution is never cheap, besides being cumbersome to deploy. of course, my opinion).

BitKoo and OpenIG have solutions that attempt to resolve this issue.




Basically, a Proxy/Gateway is introduced. This is where the access to the actual application is intercepted and password being replayed securely.




In the case of BitKoo, user credential is stored securely in a keystore.

On the other hand, OpenIG (aka ApexIdentity Gateway) integrates, out-of-the-box, with all 3rd party web access management solutions (e.g. OpenAM).

The key point is any web application can come on-board without ever modifying the target application again.


.

Friday, November 11, 2011

Policy Agent debugging



If you have deployed Policy Agent in Centralized mode and have set the debug level to Message, yet when the policy agent container is started and you only see the following:



=======================================
2011-10-31 09:56:35.408 -1 20816:1f8957d0 all: Version: 3.0-04
2011-10-31 09:56:35.408 -1 20816:1f8957d0 all:
2011-10-31 09:56:35.408 -1 20816:1f8957d0 all: Build Date: Fri Jul 29 00:05:09 BST 2011
2011-10-31 09:56:35.408 -1 20816:1f8957d0 all: Build Machine: constable.internal.forgerock.com
2011-10-31 09:56:35.408 -1 20816:1f8957d0 all: =======================================

The log is very verbose when the debug level is set to Message. Then definitely there is something wrong.

There is one more tweak to it...

Go to the ../Agent_001/config directory and amend the following 2 properties files:

1. OpenSSOAgentBootstrap.properties
2. OpenSSOAgentConfiguration.properties


Look for the following:

# AGENT DEBUG LOG LEVEL
com.sun.identity.agents.config.debug.level = all:5 (default is empty)

Restart your policy agent container. You'll see more log statements.

This method was helpful to me when there was some misconfiguration in the network or load-balancer stickiness issues. Of course, there are many more scenarios that could potentially happen.


.


Wednesday, November 9, 2011

BlackBerry Desktop Software for Mac

With BlackBerry Desktop Software for Mac, synchronizing musics from my iTunes to the smartphone has become a breeze! 


Of course, there are Calendar, Contacts, Notes and Tasks sync. But I'm using Google Calendar and not Exchange, so that's not useful for me.

.

If you are deploying SharePoint, this link is very helpful for your pre-sales activities.


There are Foundation, Standard and Enterprise editions. You need to be careful which edition to choose. Otherwise, some features might not be available.

.

Sunday, November 6, 2011

OpenAM Policy Agent - Life Cycle

I always prefer diagram to wordings. Below is an illustration on how a Centralized Agent Configuration works:





When an agent starts up, it reads its bootstrapping file to initialize itself.

OpenSSOAgentBootstrap.properties is stored on the agent machine and indicates the location from where the configuration properties need to be retrieved. Based on the repository setting in OpenSSOAgentBootstrap.properties, it retrieves the rest of its configuration properties. It fetches its configuration from OpenAM Server.

An agent fetches its configuration properties periodically to determine if there have been any configuration changes. Any agent configuration changes made centrally are conveyed to the affected agents, which will react accordingly based on the nature of the updated properties. If the properties affected are hot swappable, the agent can start using the new values without a restart of the underlying agent web container. Notification of the agent when configuration data changes and polling by the agent for configuration changes can be enabled. Agents can also receive notifications of session and policy changes.

Note:

For Apache Policy Agent, do not enable notification.
 
.

Saturday, November 5, 2011

Cluster initialization failed. Disabling the cluster service.

Switching from Solaris to Linux OS can be a challenge to me, at times.

I was installing and configuring Glassfish Message Queue for OpenAM Session Failover a month back and was not able to make it work initially.


The configuration was made exactly the same as what I would have done on a Solaris box. I have done that far too many times to have miss out anything. But.... the MQ just would not start on a Linux box!

So debugging was needed... In the end, I found the issue - "Invalid broker address for this broker to run in cluster: Loopback IP address is not allowed in broker address mq://127.0.0.1:7676/..."

I found out that in Linux OS, loopback IP is not allowed.

The resolution is to add imq.hostname in the BROKER_OPTIONS:

[lx123 ]$ cd /am/bin/sfo/bin
[lx123 bin]$ vi amsfo
BROKER_OPTIONS="-silent -Dimq.hostname=am1.lx.com"


.

Saturday, September 17, 2011

Install OpenAM Core Only

For production deployment, most customers prefer the OpenAM Administration Console not to be exposed to the Internet. Instead, they'll like the Admin Console to be accessible within the Intranet.

The solution is to deploy a OpenAM Core Only distribution in the Internet; while deploying a OpenAM Console Only distribution in the Intranet.

After deploying OpenAM Core Only, you'll still get the Login Page. There's no difference in behavior from the out-of-the-box installation.


The only difference is when you attempt to login. Once you have successfully authenticated, you'll be shown the following page.



The JSPs for the console pages have been stripped off. As such, the requested resource is not available.

This type of deployment is useful if the OpenAM Login Page is not utilized for end-users' authentication purpose.

.

Friday, September 9, 2011

OpenAM : Why is Login Page missing after reboot?

I came across this question before. Today, I encountered this scenario after my VM hung and I needed to reboot the server.


Very strange. Everything was running fine for so many days. I panicked when I have to re-configure again.

Well, after I cooled down, I then realized my OpenDJ was not started yet!! I had my OpenAM installed with configuration and user data stores in the external OpenDJ. (I did not use the embedded OpenDJ that was bundled with OpenAM)

Ok, so I shutdown OpenAM. Started OpenDJ, followed by OpenAM.



Everything is now back to normal. Phew!


Anyway, I would expect OpenAM to be smarter. At least, it should check whether or not there is an existing instance installed by looking into the .openssocfg directory.




If existing instance(s) found, then it should not redirect users to the Configuration Page.


.


LDAP Error 21: The request contains invalid syntax.


In my test environment, I have configured an external data store which is connected to OpenDJ 2.4.3. My OpenAM configuration store is connected to the same OpenDJ instance.



I was trying to perform a simple load-test and needed some test users. As such, I tried to create new users via the OpenAM Administration Console. Since "First Name" is not compulsory, I skipped that field.

No good. I encountered "LDAP Error 21: The request contains invalid syntax.".

Very strange. How can this be? When my external data store was Sun DSEE, I have never encountered the same issue before.

A look at the OpenDJ access log revealed the following:

[08/Sep/2011:14:54:43 +0800] ADD REQ conn=71 op=3 msgID=278 dn="uid=test001,ou=people,o=st701" [08/Sep/2011:14:54:43 +0800] ADD RES conn=71 op=3 msgID=278 result=21 message="Entry "uid=test001,ou=people,o=st701" contains a value "" for attribute givenName that is invalid according to the syntax for that attribute: The operation attempted to assign a zero-length value to an attribute with the directory string syntax" etime=4


A check with OpenDJ indicated that "Directory String" has a property "allow-zero-length-values" set to false by default.

How to resolve?

$ bin/dsconfig -h am1.sg.azlabs -p 888 -D "cn=Directory Manager" -w [password] set-attribute-syntax-prop \
-n --syntax-name "Directory String" --set allow-zero-length-values:true



PS: The 2 product teams (OpenAM vs OpenDJ) have to talk to each other. Both products have to work seamlessly out-of-the-box. One team has to give in to another at times. My thought.

Wednesday, September 7, 2011

OpenAM : Extending to a Dual Instance Deployment

If you are using the web-based GUI to install your 2nd OpenAM instance, you'll come to Step 3 wizard page (Configuration Data Store Settings).

Since this is the 2nd instance, we should select "Add to Existing Deployment?". Then we should key in the "Server URL" - which points to the 1st OpenAM instance.

Once the Server URL is entered, the LDAP Server will be auto-populated. Strange thing is the Port is populated with "null".


So is this going to work or not? I went ahead to continue with the installation.

The installation completed without any error! After installation, I logged into OpenAM Admin Console to double check. Everything is good. The LDAP port for my 2nd instance is reflected as "1389" - which is correct.




It's still a mystery why "null" was displayed in the installation wizard.


.

Tuesday, September 6, 2011

AM SFO: Dual instances on single machine

We have just won a project to migrate from Sun Access Manager 7 to ForgeRock OpenAM 9.5.3. This site has high concurrent access and many Policy Agents. It also needs to support Session Failover. 


There are many ways to scale OpenAM and the corresponding AMSFO.

In my test labs, I was trying to get 2 instances of AMSFO to run concurrently. I followed this Wiki (Extending to a Dual Instance Deployment) from OpenAM.

Everything runs fine for the 1st instance (port 7777). I just could not get the 2nd instance (port 8777) to start up properly on the same physical machine.

It kept throwing the following error:

Sep 6, 2011 3:06:08 PM com.sun.messaging.jmq.jmsclient.ExceptionHandler throwConnectionException
WARNING: [C4003]: Error occurred on connection creation [am2.sg.azlabs:8777]. - cause: java.net.ConnectException: Connection refused

I think there must be a mis-configuration in the Java Message Queue. OpenAM 9.5.3 uses Sun GlassFish(tm) Message Queue 4.4.

So I searched Google and located this document. I think what was missing is to instruct each MQ to bind to its own dedicated IP address ( imq.hostname - Default host name or IP address for all connection services ).

I also learnt that there are many other listening ports when AMSFO is started, besides the broker port 7777.

Before AMSFO is started:


After AMSFO is started:


So, it's very obvious there was a clash in ports when the 2nd instance was trying to start. (e.g. 50722, 55044 etc.. It's random port numbers.. But so lucky of me to keep clashing on used ports)

Resolution?

In the start-up script amsfo, edit the following:
#BROKER_OPTIONS="-silent"
BROKER_OPTIONS="-silent -Dimq.hostname=am1.sg.azlabs"
Apply the same to the start-up script in the 2nd instance, but change the imq.hostname to am2.sg.azlabs.

 

 Solved!

.


Friday, August 12, 2011

OpenSSO/OpenAM : Session Timeout for Login Page


The following is the page most customers hate. 


Unlike other web-based applications, the OpenSSO/OpenAM login page itself has a timeout value. The clock starts ticking when users land on this page. If users do not login before the timeout, the "Your session has timed out" will be displayed. The default value is 120 seconds.

How can we increase this value? This is the most common question from customer.


[openam953]$ cd /home/openam953/opt3/tomcat/webapps/openam953/config/auth/default_en
[openam953]$ vi DataStore.xml



Change timeout from 120 to 300. I personally think 5 minutes is a reasonable value. Why would one come to a Central Single Sign-On page to do nothing? Most probably, one would want to authenticate and be quickly redirected to the intended application.

I somehow had this impression that a timeout value of 0 implies there will be no session timeout. With this impression, I implemented this solution for one of my customer in one of the local ministries. The feedback was the Login Page times out even faster. Strange! :)

After much debug, I then realized 0 is not an accepted value. If 0 is input, a default value of 60 seconds will be applied.

[openam953]$ tail -f Authentication | grep -i "timeout"

Setting page timeout :60
Returning page timeout :60
Setting page timeout :120 <- Default Login Page value

Setting page timeout :60
Returning page timeout :60
Setting page timeout :600 <- This was when I set the timeout value to 600


Setting page timeout :60
Returning page timeout :60
Setting page timeout :60 <- If 0 is input, it will be replaced by 60


This default value can be found in PagePropertiesCallback.






And also, do take note of Invalidate Session Max Time in Session Limits.


The default value is 3 mins. In my case, I should set it to 6 mins instead.


.