Friday, April 15, 2011

Sun Java System Web Server 7 Policy Agent Issue

I spent almost 1.5 weeks trying to resolve a Policy Agent issue in one of my customers' environment.


Even though they have Sun Java System Web Server 7, their configuration is "ancient" type. We know that there is a modern in-built Reverse Proxy plugin in Web Server 7. But the customer is still using the legacy Glassfish Load-Balancer plugin.

Cross-Domain Single Sign-On

There is this scenario where the Web Server is residing in a different domain from OpenSSO Server.

In CDSSO mode, the agent for SJSWS does not reset the protocol version to the one from POST-request [HTTP/1.1] (received from the CDCServlet), but to a HTTP-Request version 0.9 [HTTP]. This scenario only happens in CDSSO mode due to the handling of the assertion the agent got from the CDCServlet.

Step-by-Step

1. Policy Agent intercept "GET /hello/ HTTP/1.1"
2. Since this is CDSSO, Policy Agent attempts to reset protocol version ( from HTTP/1.1 to HTTP )
3. Policy Agent then allow the request to pass to the plugin

Note: A HTTP without any version should be interpreted as HTTP 0.9, according to W3C.



This is what W3C has to say with regard to HTTP Protocol Version:

The Protocol/Version field defines the format of the rest of the request.. At the moment only HTRQ is defined. If the protocol version is not specified, the server assumes that the browser uses HTTP version 0.9.




So, what's the issue then?


Load Balancer Plugin (Web Server Access Log)

192.168.1.47 - - [13/Apr/2011:17:30:55 +0800] "GET /hello/ HTTP/1.1" 302 0
192.168.1.47 - admin [13/Apr/2011:17:31:02 +0800] "GET /hello/
HTTP" 505 0





Reverse Proxy Plugin (Web Server Access Log)

192.168.1.47 - - [14/Apr/2011:10:28:48 +0800] "GET /hello/ HTTP/1.1" 302 0
192.168.1.47 - admin [14/Apr/2011:10:28:55 +0800] "GET /hello/
HTTP" 200 327



The issue is:
a. LB-plugin: Not able to respect HTTP version 1.0 and below ("HTTP Error 505 HTTP version not supported' error)
b. RP-plugin: Able to respect HTTP version 1.0 and below


Clearly, there is something wrong with the Load-Balancer plugin. According to W3C, it has to honor HTTP and let the request to pass-through.


And, although it is fairly rare that any software/application will send a HTTP with protocol version lower than 1.0 these days, it is totally "legal" to do so.

In this case, the Policy Agent chooses to swallow a request with HTTP/1.1, but passes a request HTTP to the plugin. Rightfully, it would be ideal to swallow HTTP/1.1, and passes the same HTTP/1.1 to the plugin.




PS: Btw, I need to thank Bernhard for helping me with this issue. Thanks, Bernhard!
.

OpenDJ Directory Server

ForgeRock has done a great job with OpenDJ Directory Server so far.



So what does OpenDJ provides, in a nutshell? A diagram will be best for illustration.




For anyone interested in the details of OpenDJ, here is the latest product sheet for your reference.

.

Thursday, April 14, 2011

Web Agent Caching Behavior

I have been asked a few times by customers on how Policy Agent manages its internal cache. I think I might as well make a note of this so that I can make reference to this question again much easier next time.

There is actually a documentation on this topic here.


Summary

  1. Policy agent caches users' policies
  2. 2 mechanism are utilized: notification and/or polling
  3. Each cache entry expires in 3 minutes, by default




Firewall Consideration

The challenge comes when there is a firewall between the Policy Agent and OpenSSO Enterprise Server. In such circumstance, notification should be turned off. (Otherwise, you'll get a lot of error on the OpenSSO debug log complaining about non-contactable agents.)




Production Scalability Consideration

  1. Policy changes are frequent
  2. Sites need to accept the fact that there will always be latency to reflect policy changes
  3. No hard rule on this latency time as long as it's acceptable for the site's specific needs



    The guideline when setting the Policy Cache Polling Period property is to set it to the lower of the two:


    • The session idle timeout period
    • Site’s accepted latency time for policy changes


    .

    Tuesday, April 12, 2011

    Unable to find active Access Manager Auth server


    If a protected application is running (with Policy Agent), but the backend OpenAM/OpenSSO server is down, you'll get "Forbidden" error on the web browser.


    "Your client is not allowed to access the requested object"



    The following will be captured in the amAgent log:



    am_web_get_url_to_redirect: unable to find active Access Manager Auth server.


    .

    Monday, April 11, 2011

    ERROR: Invalid Agent: Could not get agent for the realm


    Sometimes, when CDSSO is configured, one will encounter HTTP Status 500 after a successful login.
    1. Access protected application 
    2. Redirect to OpenSSO Login Page
    3. Upon successful login, redirect back to protected application

    Step 3 is not happening. Instead, user encounters HTTP Status 500.


    If you take a look at the amAgent log on the protected application side, there is nothing unusual. All seems good. 

    Something is definitely wrong on the OpenSSO server end. 



    The problem is "Unknown Host Exception".  Add the FQDN to the /etc/hosts resolves the issue!


    .


    Monday, April 4, 2011

    OpenAM 9.5.2 CLI Configuration

    I was trying to install a new install of OpenAM 9.5.2 for a POC using the GUI Configurator. (Read here)

    The problem then was the embedded OpenDS 2.3 will always create a Administrator Connector Self-Signed Certificate using the hostname. If this hostname is not defined in /etc/hosts, configuration will bomb.

    ERROR: AMSetupServlet.configure: error
    org.opends.server.types.InitializationException: The administration connector self-signed certificate cannot be generated because the following error occurred: openam: openam
    at org.opends.server.admin.AdministrationConnector.handleCertifExceptions(AdministrationConnector.java:776)
    at org.opends.server.admin.AdministrationConnector.createSelfSignedCertifIfNeeded(AdministrationConnector.java:757)
    at org.opends.server.admin.AdministrationConnector.initializeAdministrationConnector(AdministrationConnector.java:181)


    Today, I tried to find out whether or not this can be workaround by using CLI configuration.


    SERVER_URL=http://openam.sg.azlabs:9080
    DEPLOYMENT_URI=/openam71
    BASE_DIR=/home/openam952/openam71
    locale=en_US
    PLATFORM_LOCALE=en_US
    AM_ENC_KEY=wKO7mExvCqVXETTtsgU4HgtvqBXrFzSW
    ADMIN_PWD=password
    AMLDAPUSERPASSWD=amldapuser
    COOKIE_DOMAIN=.sg.azlabs


    DATA_STORE=embedded
    DIRECTORY_SSL=SIMPLE
    DIRECTORY_SERVER=openam.sg.azlabs
    DIRECTORY_PORT=51389
    DIRECTORY_ADMIN_PORT=8888
    DIRECTORY_JMX_PORT=1689
    ROOT_SUFFIX=dc=opensso,dc=java,dc=net
    DS_DIRMGRDN=cn=Directory Manager
    DS_DIRMGRPASSWD=password


    ## Leave (blank) will default to embedded DATA_STORE
    USERSTORE_TYPE=


    No use.

    The OpenDS is still trying to create the Administrator Connector Self-Signed Certificate using the hostname.

    By the way, in OpenAM 9.5.2, with the upgrade of OpenDS from 1.x to 2.3, the following 2 attribute-value pairs are required:


    DIRECTORY_ADMIN_PORT=8888
    DIRECTORY_JMX_PORT=1689


    Quite a painful experience as the documentation wasn't there. I had to read the source code and trace what was required by the configurator.



    For those interested, I was looking at the method runOpenDSSetup (...) in EmbeddedOpenDS.java

    setupCmd[2] = (String) map.get(SetupConstants.CONFIG_VAR_DIRECTORY_ADMIN_SERVER_PORT);
    setupCmd[4] = (String) map.get(SetupConstants.CONFIG_VAR_ROOT_SUFFIX);
    setupCmd[6] = (String) map.get(SetupConstants.CONFIG_VAR_DS_MGR_DN);
    setupCmd[8] = (String) map.get(SetupConstants.CONFIG_VAR_DIRECTORY_SERVER_PORT);
    setupCmd[13] = (String) map.get(SetupConstants.CONFIG_VAR_DIRECTORY_JMX_SERVER_PORT);


    Then I went to SetupConstants.java to find out what attribute names are required:

    /**
    * Configuration Variable for directory server admin port.
    */
    String CONFIG_VAR_DIRECTORY_ADMIN_SERVER_PORT = "DIRECTORY_ADMIN_PORT";


    /**
    * Configuration Variable for directory server jmx port.
    */
    String CONFIG_VAR_DIRECTORY_JMX_SERVER_PORT = "DIRECTORY_JMX_PORT";




    .