I've been working on some cases where integration was needed with APIM Gateway with CA Single Sign-On (CA SSO). In particular I needed an sample Gateway Policy that did not update the CA SSO SMSESSION cookie for every request. But this article evolved into a bit more general one about CA SSO setup and includes some details of the basic CA SSO setup in APIM Gateway.
The core components of the SSO integration are one:
And three Policy Assertions :
- Request: Check Protected Resource Against CA Single Sign-On
- Request: Authenticate Against CA Single Sign-On
- Request: Authorize via CA Single Sign-On
The SSO configuration points you to a CA SSO policy server, and the three assertions are for : a) checking to see if a URL is "protected" by CA SSO; then b) do a user authentication (UN/PW); and c) finally check to see if the authenticated user has access to the "protected" resource.
CA SSO also uses a SMSESSION cookie to identify a user session. The cookie is quite large (~4k) and is an encrypted blob containing All the details of the user session. Alternative session schemes (say JSESSIONID) use a small identifying key, and a backend database of active "sessions". The SSO setup does not need a backend session store, but comes at the cost of a larger sized cookie.
To keep track of the user last activity time for idle timeout, CA SSO periodically updates an internal timestamp in the SMSESSION encrypted blob, and gives you a "new" 4k SMSESSION value.
The normal CA SSO webagents (apache, IIS, etc SSO agents) will update the SMSESSION cookie periodically, every 30sec, as set by ACO SessionGraceTime value. But for APIM set-cookie is controlled at the APIM Policy Manager level, and the integration with CA SSO is at the SDK level. So APIM does not automatically have this grace time ability.
Here are some scenario's for using SMSESSION cookie:
1. Not Using SMSESSION cookie
For webservice calls you may not want to keep track of a "session". One way to do that is to preemptively pass the Authenticate: header on the request (in our case just the standard HTML basic UN/PW credentials) and to effectively do a new "login" for each request. You then don't need to worry about keeping track of any SMSESSION cookies.
The disadvantage is that for each "login" (ie each request in this case ) the gateway has to send the "login" request to the policy server.
2. Using SMSESSION cookie
If you are using SMSESSION cookie, which is normal for web browser based applications, then you need to code via the APIM Policy Manager to set the SMSESSION cookie in the HTML Response back to the user.
You also need to check new requests to see if it already contains a SMSESSION cookie. And when one exists there is a different form of the call to "Authenticate Against CA Single Sign-On" to take the SMSESSION smtoken cookie value.
You also need to ensure the checkbox "Update SSO Token" is set on the "CA SSO Configuration" screen. The Authenticate call then generates an updated smtoken with a new internal timestamp.
And you need to send the updated smtoken back to the user via a set-cookie SMSESSION in the response.
3. Using SMSESSION cookie with a grace time.
This is where I started. A simple APIM Policy implementation of SMSESSION cookie updates the cookie for every request. But as per the normal webagent it's better to only update the cookie periodically, say every 30sec or so.
To do that we've implemented some APIM Policy to calculate the time difference between the last update time of the smtoken and the current time and only update the SMSESSION cookie if the cookie is over 30sec old.
4. Some Notes:
Note1: This policy is developed for CA APIM Gateway 9.2, and I've hardcoded a value of 30sec for the grace time. But for CA APIM Gateway 9.3 you can access the ACO (Agent Configuration Object) values. So you can get access to some of the CA SSO settings for : SessionGraceTime and CookieDomain rather than having to hardcode them as I have done in this example.
Note2: In my (simple) example I am sending in the Authenticate: header each time, even when I have a SMSESSION cookie. That is preemptive and simple, but in practice a 401 response would be used to trigger the sending the Authenticate header.
5. Code for Update SMSESSION cookie every 30sec
Here is the code for update of SMSESSION every 30sec (the policy is also attached as xml export).
Effectively after Authentication we set the variables lastsession and currenttime, which are the last update time for the session, and the current server time. Then we calculate the difference using XPath setting context variable timedelta.
Finally if timedelta is less than zero, or greater than 30sec we then proceed on and update the SMSESSION cookie (the less than zero is needed for the first request, where the test for the "first" create smtoken can be negative.
As mentioned I've hardcoded the cookie domain and the timeout time, if using APIM Gateway 9.3 however these values could be obtained from the CA SSO Policy Server (maybe in a latter article).
6. Code for using SMSESSION cookie
The Policy for smsession CA SSO integration with cookie is described in the Gateway documentation:
Working with CA Single Sign-On - CA API Gateway - 9.3 - CA Technologies Documentation
And here is my implementation (also included in the policy export attached):
Essentially "Check Protected" is called, the first path then checks if we have an SMSESSION cookie, and it does the Authenticate/Authorize using the smtoken from the cookie. The alternative path then uses HTTP Basic credentials to logon and create the smtoken. The third path, if both smsession and login path failed returns an template error message back to the user.
7. CA Single Sign-On Configuration
Here is my CA SSO configuration. The main point to note is that the checkbox "Update SSO Token" is checked, which gives us updated smtoken values.
8. Debug Print of smtoken context variables
Here is screenshot of the service debugger, showing the siteminder.smcontext.attributes. Note the currrentservertime is lactually earlier than the lastsessiontime, due to difference in time between the CA SSO policy server and this machine (they are however both connected to different ntp servers). We can see it is a new session since startsessiontime is the same as lastsessiontime.
Cheers - Mark