Sunday, January 31. 2010
OpenSSO Reverse Proxy Extension (Part II)
This is the second part of a three post series dedicated to OpenSSO Reverse proxy Extension. In the previous one the code of this extension was checked out and a simple Basic Auth example which is in the samples directory was tested. In this second chapter the reverse proxy is going to be extended in such a way that the software can retrieve the username/password pair from OpenSSO. This is a clear and natural extension in the goal to a robust integration between OpenSSO and the Proxy Extension.
The strategy to obtain that data is the following:
In order to achieve the four items the first step is to install OpenSSO. OpenSSO was installed in the Solaris KVM box and I decided to use the latest build (I wanted to be as close to Express Build 9 as I could). The war installation went perfect following the documentation and, at the end, a working OpenSSO was running inside a container with the user store in a external ldap server.
With the OpenSSO server up and running the next step was the installation of the SDK java example application that goes with OpenSSO bits. The opensso-client-jdk15.war was deployed into my Tomcat container following the installation guide (server runs in the virtualized Solaris and client in my debian laptop). The information I submitted was the following:
The client installation did not go as smooth as the server one. After configuration all Access Management Samples did not work at all. In previous experiences with versions 7.x cookie encoding was specially a headache and I decided to start from here. Finally I found this heaven send web page and activating c66Encode property all the samples magically started to work properly. It was quite useful too enabling debug mode. Single Sign On Token Verification Servlet is the example that lets SDK application to retrieve information from the SSO token.
When the SDK sample app was running the Post Authentication plugin had to be configured. OpenSSO is a very flexible piece of software and post auth classes are useful to execute some code after a successful login. This plugin is a standard OpenSSO post authentication class that inserts into the SSO token the username and password just logged. For example this plugin is used in IIS web agent to replay password against some applications like Sharepoint. The code of this class is in OpenSSO project and the documentation to configure it is also public.
At this point the status of my little OpenSSO installation was the following: OpenSSO was running, the post auth plugin was configured and username/password information was accessible inside token and functional client SDK sample app was running in my tomcat. Basic auth web server was also configured to access the same ldap user store of OpenSSO (this way web server and OpenSSO share the same users). So I just added the OpenSSO SDK in the proxy netbeans project (looking at the sample app) and developed the new password credential source which uses the SDK to retrieve the login information from the token. All this stuff is summarize in:
Although the complete class is presented I want to comment the code briefly. This credential source gets the SSO token. If the token exists and is valid the username must be in the sharepoint_login_attr_value property (if this property is null the usual userId is used) and the password in sunIdentityUserPassword property. But the password is encrypted (Post Auth plugin does) and the method needs to decrypt it using the previously used key. The DES key configured in the plugin must be used and it is passed to the class via the constructor. The main part of the code is the following:
Finally the BasicAuthProxy servlet is changed to use this brand new class. Now it does not use a hardcoded username/password pair but the real one.
If we try to access directly to the tomcat a exception is thrown (cos the user is not logged in OpenSSO). But if we go first to the OpenSSO server, perform a login and then access tomcat, the proxy silently retrieves my login info and logs me in to the basic auth protected web server. The username and password can be shown in the tomcat logs.
As a conclusion, this second part of the proxy extension shows a real OpenSSO use. It is clear that now the extension is not very useful (java developing is needed) but it could be. A third post will come to show a real legacy application instead of the basic auth web server.
cheerio!
The strategy to obtain that data is the following:
- The user must be previously logged in OpenSSO.
- The Post Authentication OpenSSO plugin will be needed to store in the SSO token the username and password (encrypted).
- A new class that implements PasswordCredentialSource is necessary to obtain the data stored in the second point. This class needs the integration of OpenSSO Java SDK into the proxy app.
- The BasicAuthProxy servlet must be slightly modified to integrate the new credential source class.
In order to achieve the four items the first step is to install OpenSSO. OpenSSO was installed in the Solaris KVM box and I decided to use the latest build (I wanted to be as close to Express Build 9 as I could). The war installation went perfect following the documentation and, at the end, a working OpenSSO was running inside a container with the user store in a external ldap server.
With the OpenSSO server up and running the next step was the installation of the SDK java example application that goes with OpenSSO bits. The opensso-client-jdk15.war was deployed into my Tomcat container following the installation guide (server runs in the virtualized Solaris and client in my debian laptop). The information I submitted was the following:
Server Protocol | http |
Server host | solaris10.demo.kvm |
Server post | 8080 |
Server deployment URI | /opensso |
Debug directory | /home/ricky/logs |
Application user name | amadmin |
Application user password | adminadmin |
The client installation did not go as smooth as the server one. After configuration all Access Management Samples did not work at all. In previous experiences with versions 7.x cookie encoding was specially a headache and I decided to start from here. Finally I found this heaven send web page and activating c66Encode property all the samples magically started to work properly. It was quite useful too enabling debug mode. Single Sign On Token Verification Servlet is the example that lets SDK application to retrieve information from the SSO token.
When the SDK sample app was running the Post Authentication plugin had to be configured. OpenSSO is a very flexible piece of software and post auth classes are useful to execute some code after a successful login. This plugin is a standard OpenSSO post authentication class that inserts into the SSO token the username and password just logged. For example this plugin is used in IIS web agent to replay password against some applications like Sharepoint. The code of this class is in OpenSSO project and the documentation to configure it is also public.
At this point the status of my little OpenSSO installation was the following: OpenSSO was running, the post auth plugin was configured and username/password information was accessible inside token and functional client SDK sample app was running in my tomcat. Basic auth web server was also configured to access the same ldap user store of OpenSSO (this way web server and OpenSSO share the same users). So I just added the OpenSSO SDK in the proxy netbeans project (looking at the sample app) and developed the new password credential source which uses the SDK to retrieve the login information from the token. All this stuff is summarize in:
- Adding openssoclientsdk.jar to the project.
- Adding a working AMConfig.properties configuration (copied from the client app) in WEB-INF/classes root directory.
- And finally developing the PostAuthCredentialSource.java class.
Although the complete class is presented I want to comment the code briefly. This credential source gets the SSO token. If the token exists and is valid the username must be in the sharepoint_login_attr_value property (if this property is null the usual userId is used) and the password in sunIdentityUserPassword property. But the password is encrypted (Post Auth plugin does) and the method needs to decrypt it using the previously used key. The DES key configured in the plugin must be used and it is passed to the class via the constructor. The main part of the code is the following:
// Get the SSO token from SSO session
SSOTokenManager manager = SSOTokenManager.getInstance();
SSOToken token = manager.createSSOToken(req);
// check if the token is valid
if (manager.isValidToken(token)) {
// get the user password. PostAuth use sunIdentityUserPassword
// property but this is encrypted using DES. deskeystr has the
// key to decrypt password
String encBase64Password = token.getProperty("sunIdentityUserPassword");
// get the userId. PostAuth use sharepoint_login_attr_value
String userId = token.getProperty("sharepoint_login_attr_value");
if (userId == null) {
// if null use the normal user id
userId = token.getProperty("UserId");
}
// decode password using the key in deskeystr
BASE64Decoder decoder = new BASE64Decoder();
byte[] encPassword = decoder.decodeBuffer(encBase64Password);
byte[] desKey = decoder.decodeBuffer(deskeystr);
SecretKeySpec keySpec = new SecretKeySpec(desKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] password = cipher.doFinal(encPassword);
// set user and password in credentials to be used by the proxy
credentials.username = userId;
credentials.password = new String(password).trim();
System.err.println("Username: " + credentials.username);
System.err.println("Password: " + credentials.password);
}
Finally the BasicAuthProxy servlet is changed to use this brand new class. Now it does not use a hardcoded username/password pair but the real one.
public class BasicAuthProxy extends SimpleProxyServlet{
@Override
public void init() throws ServletException {
init("http", "192.168.122.11", 81);
addFilter(new HttpBasicAuthFilter(
new PostAuthCredentialSource("8uDWeq1Mx/c="),
new TemporaryStorage()));
}
}
If we try to access directly to the tomcat a exception is thrown (cos the user is not logged in OpenSSO). But if we go first to the OpenSSO server, perform a login and then access tomcat, the proxy silently retrieves my login info and logs me in to the basic auth protected web server. The username and password can be shown in the tomcat logs.
As a conclusion, this second part of the proxy extension shows a real OpenSSO use. It is clear that now the extension is not very useful (java developing is needed) but it could be. A third post will come to show a real legacy application instead of the basic auth web server.
cheerio!
Comments