In a previous post I presented some SiteMinder “mock” agents which I created to ease the development of SSO applications with CA® SiteMinder. Now I will dedicate this post to talk more about the general experience of using SSO with SiteMinder and WebLogic, and some tips and tricks to accomplish this task rounding some common problems.
As I described in the post “SiteMinder WebLogic Security Provider Mock”, the authentication flow we achieve is:
- User requests for a protected page;
- SiteMinder agents redirects to an single unified login page, propagating the context of the original request;
- User enter his credentials on the unified login page;
- The unified login page authenticates the user against SiteMinder directories and redirects to the original page;
- User sees the protected page (with his valid “UserPrincipal” in the security context).
Particularly I didn’t find much reference on the internet about projects like this, what made the solution design a little hard, but the hands on allowed us to realize some interesting things about the case and I will dedicate this post to tell a little about these.
Should We Use Only ASA, Only WAS, Or Both ?
This is one of the main questions our time made during the solution design. In order to contextualize, the Application Server Agent (ASA) is a SiteMinder component responsible for integrating the Application Server with the SiteMinder Server. CA provides specific ASA distributions for each of the major application servers in the market, in our case, Oracle WebLogic Server 11g. The ASA is usually a package of some java libraries and some JAAS components to deploy to the application server. The Web Server Agent (WSA) is another SiteMinder component responsible for integrating the Web Server with the SiteMinder Server. There are also specific WSA distributions for the main web servers, most commonly Apache, or in our case, Oracle HTTP Server 11g, which is much similar to Apache.
Well, if you deploy only the ASA and make some tests, it will look like you site is protected. By the other hand, if you deploy only the WSA it will look like your site is protected also. But when you go deep in the tests, you will notice that you need the both of them.
The table below summarizes the behavior of an application when only protected by ASA, and the last column shows the final behavior when we add the WSA:
Web Application Context | SiteMinder Application Server Agent Behavior | SiteMinder Web Server Agent Behavior | ||||
Accessed Resource | JSESSION_ID | SMSESSION | Expected Behavior | JAAS Security Principal | Web Agent Behavior | |
1 | Public | None or Not Authenticated | None | Grant acess | No | None |
2 | Public | None or Not Authenticated | Valid | Grant acess | Yes | Recycle SMSESSION and add SM HTTP Headers (like SM_USER and SM_SERVERSESSIONID) |
3 | Public | None or Not Authenticated | Invalid or Expired | Grant acess | No | Set SMSESSION = LOGGEDOFF |
4 | Public | Authenticated | None | Grant acess | Yes | None |
5 | Public | Authenticated | Valid | Grant acess | Yes | Recycle SMSESSION and add SM HTTP Headers (like SM_USER and SM_SERVERSESSIONID) |
6 | Public | Authenticated | Invalid or Expired | Grant acess | Yes | Set SMSESSION = LOGGEDOFF |
7 | Protected | None or Not Authenticated | None | Redirect to login page (by ASA) | No | Redirect to login page (by WSA). Obs.: using the SMWebAgentFilterMock, the first redirect will still be made by ASA and only the subsequent by the filter (due to JEE architecture restriction), but the result is the same. |
8 | Protected | None or Not Authenticated | Valid | Grant acess | Yes | Recycle SMSESSION and add SM HTTP Headers (like SM_USER and SM_SERVERSESSIONID) |
9 | Protected | None or Not Authenticated | Invalid or Expired | Deny access with HTTP 403 error | No | Set SMSESSION = LOGGEDOFF and redirect to login page (by WSA) |
10 | Protected | Authenticated | None | Grant acess | Yes | Redirect to login page (by WSA) |
11 | Protected | Authenticated | Valid | Grant acess | Yes | Recycle SMSESSION and add SM HTTP Headers (like SM_USER and SM_SERVERSESSIONID) |
12 | Protected | Authenticated | Invalid or Expired | Grant acess | Yes | Set SMSESSION = LOGGEDOFF and redirect to login page (by WSA) |
The main problems of the only ASA approach are the lines 9, 10 and 11 highlighted above:
- Line 9 – protected resource with an empty java session and invalid SiteMinder token
Due to Java Authentication and Authorization Services (JAAS) architecture limitations, the Servlet Authentication Filter (SAF) component inside the WebLogics ASA Security Providers intercepts the request only when you don’t have an authenticated session neither a security token. The SAF component is an extension to JAAS which acts before the authentication providers and permits that a request to be redirected. When you already have the security token, regardless it is invalid or not, the SAF component will not run. In this case, only the Identity Asserter Provider (IAP) runs, and IAPs are not capable to do any redirects, then considering this limitation, a HTTP 403 error is the best an IA can do in this case.
- Line 10 – protected resource with an authenticated java session and no SiteMinder token
When you already have an authenticated user into a valid Java HTTP Session, the security providers don’t act anymore, regardless of the SiteMinder token. That is, the JSESSIONID is “commanding” the authentication. This can be a really bad side effect when you talk about SSO between multiple applications which don’t share the same JSESSIONID, because some user can authenticate in other application with other credential and acquire a SiteMinder SMSESSION, and when he comes back to the original application, the credential on the JSESSIONID will override the SMSESSION, breaking the SSO (in fact a bad security risk).
- Line 12 – protected resource with an authenticated java session and invalid SiteMinder token
Because the same reasons of the line 10 (JSESSIONID “on charge”), the ASA providers are not called to do any checks on the SiteMinder token if the user already has an authenticated java session.
The three points above make clear that only ASA is not sufficient to do the SSO with SiteMinder. Looking to the column on the right, we see that adding WSA causes the expected SSO behavior. As WSA stays in a layer before the application server, WSA can always check the SiteMinder token and work on it before it reaches the WebLogic, making now the SMSESSION “on charge”. This way, the only work ASA does is building the Security Principal from the SMSESSION token.
Now you could be questioning… Why not then use only WSA?
- Different from an application which runs in one single web layer (like PHP), we have here two distinct layers which is the Web Server and the Application Server. So if we protect only the Web Server layer, it causes an internal security problem, because anyone who makes direct access to the application servers host and port will gain full access to the application;
- Supposing that you are not concerned about internal fraud and block your application server direct access through firewall, then you would need to make some logic to get the “SM_USER” request header injected by WSA to protect your application. It is a bad JEE practice because you would be doing some sort of homemade security treatment, instead of using the JEE security standards, and something like a NullPointerException not discovered in the tests could compromise the whole application security, besides increasing the internal fraud effect by the ease of impersonate any user.
- Like any other kind of trust between two parts based on some token, if one part (aka web layer) generates the SMSESSION token, the other part (aka application layer) must validate the token in order to guarantee the trustworthiness and integrity of the token. This is what ASA Identity Asserter does, plus building a trustful security context for JEE standard security development based on the container.
JEE Web Application Configuration
Starting from the point that you already have an up and running SiteMinder, ASA and WSA installed and configured correctly (this can be accomplished by reading the SM manuals), you must configure your JEE Application. The main points of this configuration are in the descriptors “web.xml” and “weblogic.xml”, as show below:
– Descriptor “web.xml”:
<!-- This is the default JAAS token based auth method --> <login-config> <auth-method>CLIENT-CERT</auth-method> </login-config> <!-- Declare all the roles used by your application --> <security-role> <role-name>LoggedUsers</role-name> </security-role> <!-- Declare your protected resources --> <security-constraint> <web-resource-collection> <web-resource-name>Protected resources</web-resource-name> <url-pattern>protected/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>LoggedUsers</role-name> </auth-constraint> </security-constraint>
– Descriptor “weblogic.xml”:
<!-- Mapping between app roles and server principals (in this case, any valid user) --> <security-role-assignment> <role-name>LoggedUsers</role-name> <principal-name>users</principal-name> </security-role-assignment>
In order to use ASA and WSA, you must define your protected resources into both “web.xml” security constraints AND you app’s Domain/Realm on SiteMinder. This duplicated configuration is necessary because the JEE security constraints enables ASA interception and SM’s domains/realms enables WSA interception.
Tips and Tricks
- Always develop standard JEE security using JAAS (homemade security is risk full);
- Never trust only in “SM_USER” header (internal fraud);
- Always trust in the container JAAS Security Principal – request.getUserPrincipal();
- Even using ASA with WSA, there may be some scenarios in which the authenticated user in JSESSIONID is different than the SSO user present in the SMSESSION cookie. This can be happen, for example, when a user switches applications in different logged states, without invalidating the java session in the original application, meaning switched users. One tip to resolve this issue is to make a Servlet Filter in the web application which intercepts all requests and do a check between the “SM_USER” request header (injected by WSA) and the Security Principal fulfilled in the security context. If the values are different, this filter should invalidate the session and send a redirect to the same requested URL. This will guarantee the synchronism between SMSESSION and Security Principal;
- Be careful about JSESSIONID implicit sharing or overriding: if you have 2 web applications running in the same WebLogic domain using de default JSESSIONID cookie name and path, these applications will implicitly share the authenticated Security Principal, so you could think that SiteMinder is working when it’s not. To avoid this behavior you can define different JSESSIONID cookie name and/or path in the “weblogic.xml” descriptor for each application;
- When developing your own unified login page, reuse the default login page provided by SiteMinder “login.fcc” by backend, making a “backend HTTP POST” and propagating the cookies returned on the response (don’t expose the “login.fcc” page directly); a more elegant solution is to use the SiteMinder Secure Proxy Server (SPS), which contains a set of WebServices that provides some login operations on top of SiteMinder, so your login page can authenticate against the “AuthAZService.login” operation and put the returned attributes as cookies in the HTTP response to the user;
- Be very careful about enabling the functionality to propagate original requests of type POST after the user logs in. If your project sponsor really wants this requirement, then implement some anti-CSRF (Cross-Site Request Forgerie) mechanism in your application. To explain better, imagine a case of a very important and transactional POST inside your site protected area, like “http://bank.example.com/withdraw?account=bob&amount=1000000&for=Fred”. If you enable the POST propagation after login, some malicious web site can add a link which submits some hidden form to your application transactional POST. In this case, the login page will be shown to the user, and after the user authenticate successfully, your login page could perform the malicious POST, making catastrophic side effects.
Good luck !!!