Improved & Simplified Web Security with SSO
Achieving Seamless Login between Web apps Deployed on WLS v7.0 & v8.1
This article presents a solution for single sign-on (SSO) between two Web applications (deployed on WebLogic v7.0 and v8.1 servers respectively) that I was recently involved in designing and developing. We will step through the different options that were considered, before presenting a detailed description of the final solution and its associated security considerations (threats and mitigating factors).
Introduction
Users need to work with a number of IT systems and applications to accomplish their job functions, and each such system has a security framework that requires users to authenticate to it before they are allowed access. This implies a multitude of sign-on dialogues, and users are required to remember and enter the correct set of credentials for each of them. This has often been a bane for security since users often write down this confidential information so as to not have to remember it all the time. Additionally, to ensure that the overall security is not compromised, administrators have to manage multiple accounts for the same user in each of those systems.
Single sign-on (SSO) is a mechanism that allows a user to access all systems and resources to which he/she is authorized following a single act of user authentication. The advantages of SSO are:
- Improved security - security is improved since there is no longer a need for the user to have to remember multiple sets of credentials. Simultaneously, user productivity is greatly enhanced since he/she must no longer navigate through the sign-in dialogues before getting down to work.
- Improved response time - administrators are able to improve their response times for tasks such as adding / removing users and modifying their access rights. Simultaneously, their ability to maintain user accounts across all systems and applications (in a consistent manner) is enhanced, which also leads to improved security.
More details on SSO can be found here: http://www.opengroup.org/security/sso/
I recently worked on designing an SSO solution between two Web applications. The two applications were related in terms of the functionality they offered to end-users. The first application (referred to as WebModuleA henceforth) was deployed in a cluster of WebLogic v7.0 servers (server1.infosys.com), which was deployed in one WebLogic Server (WLS) domain (X). The second application (referred to as ProtectedApp henceforth) was deployed in a cluster of WebLogic v8.1 servers (server2.infosys.com), which was deployed in another WLS domain (Y). Although both clusters / applications shared the same top level DNS domain (infosys.com), they were being managed by two different infrastructure teams.
Following is a schematic representation of the above scenario:

Figure 1: Web Applications deployed on WebLogic Servers v7.0 and v8.1
The SSO requirements were as follows:
- An end-user would be required to authenticate before she could access (the protected parts of) WebModuleA. The user would submit her ID/Password via the login page and the configured authentication provider on the WL 7.0 Server would validate these credentials against a corporate wide LDAP Server.
- A specific page of WebModuleA would display a link to a resource (that would be generated dynamically, by ProtectedApp, per user). However, the user had to be seamlessly authenticated to the WL 8.1 Server (as opposed to being prompted for credentials) so that ProtectedApp could generate and provide the desired resource after getting the user identity.
- The user would be free to navigate to ProtectedApp and ask for the same resource directly, however. In this case, the user would have to be shown the login page of ProtectedApp and enter her ID/Password (which would be validated by the configured authentication provider of WLS 8.1 against the same corporate-wide LDAP Server).
Since the WLS security architecture (http://edocs.bea.com/wls/docs81/secintro/index.html) is very comprehensive and extensible, my first reaction was to check if this requirement could somehow be met by the built-in support for SSO in WLS. Built-in SSO support in WLS
By default, WLS assigns the same cookie name (JSESSIONID) for all Web applications deployed on a server instance. Therefore, once a user has authenticated herself while working with one application on that server, she is seamlessly authenticated to all other applications on that server (http://edocs.bea.com/wls/docs81/security/thin_client.html#1039551).
Additionally, WLS provides support for SSO between members of a server cluster (that is, users can be seamlessly failed-over and load-balanced between two servers in a cluster without being prompted for authentication again). It is also possible to extend SSO support to servers within the same DNS domain that are not part of the same cluster, provided that the user session has been configured for persistence (in a file / database) (http://dev2dev.bea.com/products/wlserver/whitepapers/WP_WLS7_SingleSignOn.jsp). SSO via Identity Assertion
The basic tenet of any SSO solution is Identity Assertion (IA). IA works like this: first, the user authenticates herself to a system "A". The authentication service of system "A" issues her a token that securely asserts her identity (representing a trusted relationship between the user and "A"). Following this, the user tries to access a resource belonging to system "B", presenting the authenticator token with the access request. The authentication service at system "B", through a protocol previously agreed to between the two, tries to validate the authenticator token. If the validation succeeds, "B" trusts this token to have come from "A". This leads to "B" transitively trusting the user, without her having to explicitly present her credentials to B's authentication service.
The built-in support for SSO in WLS uses the JSESSIONID session cookie as the authenticator token.
Another recent initiative that has SSO as one of its stated objectives is Security Assertion Markup Language (SAML). SAML is an XML-based standard, developed under the OASIS umbrella, for exchanging authentication and authorization information between security systems. A SAML "name assertion" is an example of such an authenticator token that conveys information about the act of authentication by a specific principal. More details on SAML can be found here: http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=security.
However, following the SAML spec to the letter was felt to be too heavy weight for this relatively straightforward SSO requirement. Essentially, SAML sets up a common vocabulary for two independent applications (that may have even discovered each other only dynamically) to be able to exchange security assertions that both sides know to produce and consume. In this case, since the two applications were part of a "closed" system, there was no need for the assertion token to be encoded exactly as per the SAML spec. In fact, trying to follow the SAML spec would have entailed developing SAML-aware producer / consumer components (resident on the WLS 7.0 side and the WLS 8.1 sides, respectively). There are some SAML implementations available in the open source domain (for example, http://www.opensaml.org), that provide artifacts to build such SAML-aware components, but the effort of learning to use them would have been an overkill. WLS Security Architecture and Identity Assertion
The WLS Security Architecture supports security providers that plug into the active security realm of the server to provide security services to applications. Although the server ships with a default set of such providers, it can also be replaced with custom ones. Different types of providers are supported, but the ones of interest to us (in this problem context) are the IA providers. Please refer to http://edocs.bea.com/wls/docs81/secintro/archtect.html#1064850 for more details on the provider-based security service architecture of the WLS.
An IA provider is essentially a specialized form of the WLS Authentication Provider, which allows users to assert their identity using tokens. In the WLS, each IA provider is configured to handle a specific token type. (Details regarding the nature of the token accepted by an IA provider must be provided while deploying / configuring it). Any Web application that is deployed in the WLS with the <auth-method> element (within the <login-config> section) set to "CLIENT-CERT" is a candidate for authentication via IA. However, the Web application does not dictate the kind of token it requires for authentication. Instead, the client is required to know the right kind of token that must accompany a request to access a "resource" belonging to this Web application. The token can be sent along with the request in multiple forms (request header, cookie, X.509 certificate passed via the SSL handshake, for instance).
The WLS will determine the correct IA provider instance (among the many IA providers that may be configured on that server instance) that should be called upon to authenticate the user, by matching the token type passed with the request against the token type that each provider has indicated support for during configuration. The token is extracted from the request and passed to the IA provider as is. The provider must try and validate the token and, assuming that happens successfully, map the user identity asserted by the token to a corresponding identity in the context of this WLS.
Following these steps, the IA provider returns the user identity to the WLS via a JAAS CallbackHandler (that contains this identity). The WLS then calls on the configured Authentication Provider to authenticate the user, passing the CallbackHandler obtained previously to the constructor of the corresponding LoginModule. The LoginModule creates a NameCallback and passes it to the CallbackHandler for handling. The CallbackHandler places the asserted user identity into the NameCallback object and returns it to the LoginModule. The LoginModule can run additional checks on this identity (the user must exist in the authentication repository, the user status must be enabled, and the user must be allowed to login at the present day / time-of-day etc.). If all checks pass, the LoginModule determines the roles assigned to the user and inserts "Principal" objects corresponding to the user and the associated roles into the "Subject" (also passed to it by the WLS).
At this point, the usual J2EE authorization kicks in - the user is allowed to access the requested resource provided the correct role is present in the "Subject" corresponding to this user. Overview and Implementation of the Proposed Solution
I decided to go with the IA provider based approach outlined above because of the out-of-box support for it in the WLS.
A custom IA provider was developed and deployed in the WLS 8.1 instance; it was configured to handle tokens of the type "SETLSSOToken". Similarly, a custom Authentication Provider (with a corresponding Login Module) was deployed in the server; it can create the "Subject" for the user based on the asserted user identity provided by the custom IA provider. Meanwhile, "ProtectedApp" was deployed on this server with <auth-method> set to "CLIENT-CERT". Note that this configuration will create a problem if a user tries to access the application directly (wherein the request is not accompanied with a recognizable token) - the WebLogic server will reject the request without bothering to show the login page. We will look at how to address this problem later on in this article.
On the WLS 7.0 server, "WebModuleA" was deployed under an <auth-method> of "FORM". The user is prompted to enter her ID (or Password) to authenticate to the server before being allowed to access the resources of "WebModuleA".
One such resource was a page containing the link to the protected resource (represented here by the JSP page "ProtectedAppPage.jsp") belonging to "ProtectedApp". However, this link does not directly point to "ProtectedAppPage.jsp". Instead, it points to a token-generator component hosted on the same server (that is, WLS v7.0), with the URL of the "ProtectedApp" being provided as a query parameter to this component. In our case, this token-generator component has been implemented as a Servlet (called RedirecterServletA, deployed as a separate Web application called "RedirectA").
As an example, the link displayed by the "WebModuleA" page would look like this (shown without the URL encoding that would be done in an actual implementation):
https://server1.infosys.com:5555/RedirectA/
RedirecterServletA?resourceURL=https://server2.infosys.com:7777/
ProtectedApp/ProtectedAppPage.jsp
A user who wishes to navigate to the "ProtectedAppPage.jsp" will click on the above link (she would have been authenticated by the WLS 7.0 server at this point). The request will reach the "RedirecterServletA" component, which will extract the authenticated user identity (via "getUserPrincipal") and generate a token asserting the said identity.
The token structure will be as follows: T = <UserId> + <CurrentTimestamp> + HMAC-SHA1k(<UserId> + <CurrentTimestamp>) Here, k is a secret key shared between the WLS 7.0 and 8.1 servers via some out-of-band mechanism and HMAC-SHA1 is the cryptographic hash function described in http://www.faqs.org/rfcs/rfc2104.html. The <CurrentTimestamp> essentially functions as a means to ensure the freshness of the generated token, guaranteeing thereby that a stale token cannot be replayed after a certain point in time.
Also note that it doesn't matter whether "RedirecterServletA" is deployed in its own independent Web application (as has been done here) or included within "WebModuleA". In either case, the built-in SSO support in WLS 7.0 guarantees that once a user has been authenticated to "WebModuleA", the call to "getUserPrincipal" within "RedirecterServletA" will succeed.
Following the token generation, "RedirecterServletA" adds the following HTTP cookie to the response: Cookie Name: SETLSSOToken
Cookie Value: Base64-encoding (iatoken=<T>) where T is as generated above.
Cookie Domain: .ad.infosys.com
Cookie Path: /
Cookie setSecure: TRUE The browser will then be redirected to the URL contained in the query parameter (In the above example, the browser will be redirected to: https://server2.infosys.com:7777/ProtectedApp/
ProtectedAppPage.jsp) The browser will automatically include the above set cookie with this redirected request to "ProtectedApp" (since the DNS domain of this server matches the cookie domain). Since the request is for a Web application protected by "CLIENT-CERT", WLS 8.1 will iterate through the list of configured IA providers looking for a suitable provider that can handle the IA token of type "SETLSSOToken". Our custom IA provider will be called to validate the identity asserted by the token (passing the cookie extracted from the request to this provider).
The custom IA provider will run through the following steps:
- It will parse the token contents into the user ID, the timestamp, and the hash value.
- It will ensure that the timestamp extracted from the token does not differ from the current timestamp at its end by more than a certain pre-configured value. If not, it will throw an "IdentityAssertionException". This guarantees that the window of exposure due to a token being stolen and replayed later can be made arbitrarily small (by configuring the value appropriately).
- Based on its knowledge of the secret key k, it will compute the value of HMAC SHA1k(
+ and compare this generated value with the hash value portion of the token. If the two don't match, it will throw an "IdentityAssertionException".) - If the control flow reaches this point, the token is deemed to be valid. This prompts the IA provider to create a custom CallbackHandler object with the above user identity placed inside it. This CallbackHandler is then returned to the WLS.
The rest of the steps in the authentication process work similar to the general description in the WLS Security Architecture and Identity Assertion section and will not be repeated here for brevity.
As previously described, if one were to access "ProtectedApp" (deployed under <auth-method> of "CLIENT-CERT") directly, the result would be that WLS 8.1 would promptly reject all such requests since they would not be accompanied with a recognizable token! In short, the solution hasn't yet satisfied the third requirement (namely, to be able to access the protected resource of "ProtectedApp" directly, at which point the user should be shown the proper login page and allowed to login by providing her credentials).
One way to resolve this is to have another component (which, in our solution, has been implemented as a Servlet called "RedirecterServletB") deployed as an independent Web application ("WebAppC"). This Web application will have <auth-method> set to "CLIENT-CERT" while "ProtectedApp" will have <auth method> set to "FORM". The "RedirecterServletA" will redirect the user to this second Servlet (and not to "ProtectedApp") as follows (shown here without the URL encoding): https://server2.infosys.com:7777/WebAppC/
RedirecterServletB?resourceURL=
https://server2.infosys.com:7777/ProtectedApp/
ProtectedAppPage.jsp The request to "RedirecterServletB" will cause the user to get authenticated at the second WLS (as described before). "RedirecterServletB" will then redirect the user to the resource URL contained as a query parameter (that is, to https://server2.infosys.com:7777/ProtectedApp/ProtectedAppPage.jsp). As part of this redirect sent to the browser, "RedirecterServletB" will also ask the browser to expire the "SETLSSOToken" cookie. The browser will remove this session cookie from its memory before sending the user to "ProtectedApp". At this point, the user will be automatically authenticated to "ProtectedApp" (via the WLS 8.1 built-in SSO, since she is already authenticated via "WebAppC").
Now that we have ensured that all the three requirements (listed in the beginning of the article) have been covered, let's look at the security considerations of the proposed solution. Security Considerations of the Proposed Solution
The following security considerations must be kept in mind while thinking about the above-mentioned solution.
Key Management Infrastructure
Threat description - The first consideration on which the trust model relies is the underlying key management infrastructure. A malicious third party that comes to know the secret key k will be able to generate arbitrary assertion tokens. Therefore, it is imperative that k be established and stored very securely to ensure that only the "RedirecterServletA" component (on the first server, WLS 7.0) and the custom IA provider component (on the second server, WLS 8.1) have access to it.
Threat mitigation - For our purposes, a detailed cost-benefit analysis was done for this risk before deciding that it was sufficiently secure for the (randomly-generated) secret key to be encrypted and stored in a file with restricted access rights at the OS-level. The 3DES encryption of the secret key was done using an encryption key which was composed from two parts - one being stored in the LDAP Server and the other being stored in a file (also with OS-level access restrictions).
Other applications that deem this risk higher might want to look into the option of storing this secret key in a tamper-resistant hardware device, such as ERACOM ProtectServer Orange, Rainbow Chrysalis Luna2 and nCipher nShield.
An alternative to using a shared, secret-key is to use PKI instead. The HMAC-SHA1 operation can be replaced with a digital signature computation using the private key of "RedirecterServletA". On the receiving end, the custom IA provider can use the corresponding public-key certificate (which must be available along with the CA signer chain going up to the root CA) to validate the digital signature. Of course, "RedirecterServletA" will still need to use a password to extract and use its private key from the key-store.
Token Confidentiality and Integrity
Threat description - A malicious user can steal / modify an IA token on the wire (as it is traveling between the browser and the components of the two Web applications) to either replay the token at a later time or to launch a denial of service (DoS) attack.
Threat mitigation - Since all communication (between the browser and the two Web applications) occurs over SSL-encrypted links, it ensures the confidentiality and integrity of the token on the wire.
Clock Synchronization
Threat description - If the clock skew between the two servers exceeds a maximum allowed value, the token produced by "RedirecterServletA" will be rejected by the custom IA provider on account of it being stale. Thus, if an attacker can get the two clocks to go out-of-sync, a DoS attack can be launched.
Threat mitigation - The clocks on the two servers can be independently synced up with the standard time distribution, provided via the Network Time Protocol (NTP). This will ensure that the clock skew is kept to a minimum. More details on NTP can be found here: http://www.faqs.org/rfcs/rfc958.html.
Threat description - A valid user can use a custom browser that caches a previously issued IA token and replays it multiple times from different machines.
Threat mitigation - The window of opportunity (that is, the maximum allowed difference between the timestamp contained in the token and the current timestamp at the second server) can be made arbitrarily small, thereby reducing the chances of such an "attack". Also, the IA provider could be further customized to keep track of the timestamp (that it has last processed successfully) and throw an IdentityAssertionException if a token containing a timestamp equal or earlier than that timestamp is again presented to it. Of course, this solution will be much harder to implement in a cluster-wide deployment situation as compared to in a single-server deployment.
Theft of User Authentication Information
Threat description - An adversary could steal a user's credentials when they are being presented to the first server (and impersonate that user at a later time).
Threat mitigation - Since credentials always travel over an SSL-encrypted link between the browser and the security service of the first WLS, it is not possible to steal them on-the-wire.
Conclusion
In this article, I have presented an SSO solution for seamless authentication between two applications deployed on two WLS clusters consisting of v7.0 and v8.1 servers respectively. I have also looked at the security considerations of the solution from a point of view of the underlying threat and the mitigation technique for the same.
Although this solution was built on the basic blocks made available the WebLogic security infrastructure, the technique itself simply consists of establishing trust between two parties - the initiating party that issues the token and the relying party that validates the token. In that sense, it is general enough to be used for single sign-on between any server types (which need not even be from the same vendor). The only requirement is, of course, for the issuing and relying parties to be available and plugged into the respective security infrastructures at the two ends. These two "parties" can even be developed as reusable components of a generic security framework. About the Author
Abhijit Belapurkar has a bachelor of technology degree in computer science from the Indian Institute of Technology (IIT), Delhi, India. He has worked in the areas of architectures and information security for distributed applications for almost 10 years and has used the Java platform to build n-tier applications for more than five years. He presently works as a senior technical architect in the J2EE space, with Infosys Technologies Limited, Bangalore, India.


