Symantec Access Management

Tech Note : how to return larger data blobs (> 4k) from a custom auth scheme 

Sep 25, 2018 05:35 AM

1. Overview 

 

 

Our authentication scheme needed to return a 10k image from the CA SSO Policy Server back to the user.  Since the The image size was larger than 4k that caused some problems.  

 

Our setup is fairly simple : 

Client --> WebServer --> PolicyServer 

We do not have much control over the WebServer, but can write custom auth schemes, and .fcc pages with embedded javascript.  Normally to pass data back to a client, one would use a custom auth scheme calling setUserText() which results in a SMUSRMSG cookie being generated, followed by a redirect to another .fcc page, which then embeds the content into the page via $$SMUSRMSG$$ tag. 

 

But there are problems passing cookie values greater than 4k and we had to find an alternative pathway.  Here is a list of the limitations we found. 

 

  • Cookie Size Limitations 
    • SSO Policy Server Limit:
      • The Policy Server has a hardcoded buffer limit of 4k for SMUSRMSG.
        (we actually got a custom build with this limit increased, for testing purposes, but then hit the following browser limits)  
            

    • Browser Limits :  
      • Most browsers have a limit of about 4k for an individual cookie size. .
        https://stackoverflow.com/questions/640938/what-is-the-maximum-size-of-a-web-browsers-cookies-key 
        http://browsercookielimits.squawky.net/  
        So we tried making multiple cookies each returning a portion of the data blob.

      • Some browsers (Safari in our case) have a limit on the maximum size of all cookies from a site.
        http://browsercookielimits.squawky.net/ 
        So we also made multiple requests to the server, each getting a part of the data. .

      • There is usually a limit on the "header" part of the response from a webserver.
        HTTP requests all have a "header" and a "body", the header size is often restricted to some value, since the whole header has to be read before it is assessed, and then the following un-restricted body is read.  Our data had to travel as cookies.  However it was the other limits were the ones we hit first.

 

2. Solution 

Our workaround was to use javascript in the .fcc page to make two additional calls to the policy server.  The first generated the image and stored it as an attribute in the user store - much like the "challenge" field.  The first request then returns part of the data, and the second call returned the remaining data.  The Javascript code then merged the data and displayed the image.  

 

2.1 Solution in action

 

We want to access a resource, be redirected to the login page, and in addition the logon button, we want to be able to click an alternative "Gen Challenge" button

 

That then generates a picture "challenge" for us to use: 

Image courtesy of Michael Leunig - for more of his cartoons and art work visit https://www.leunig.com.au/  

 

That is our very simple test case. 

 

2.2 Solution Outline

Our solution is to craft some javascript code that will make more than one call to .fcc pages and each return part of the data as cookies and once we have the data, then we merge the results into the graphic blob and push them into the page. 

 

The first call from our javascript client will be :

a) Use UN/PW to call SSO custom auth scheme that :

b) validate the UN/PW and if ok then generates the image;

c) stores the image in a user attribute;

d) Returns a challenge result. 

e) On the challenge response we set two cookies sending part1 and part2 of the image.

 

The second call from the client :

a) Use UN/PW to call a 2nd SSO custom auth scheme that :

b) validate the UN/PW 

c) Returns a challenge result. 

d) On the challenge response we set two cookies sending part3 and part4 of the image.

 

 

Note: For security both calls to the .fcc page, require the user to pass the valid UN/PW before any of the challenge cookies are returned.   The cookie responses are keyed to OnAuthChallenge responses.  Alternatively some sort of access key could have been generated on the first challenge, stored in the SMUSRMSG cookie perhaps, and that used as the password - or combined with the password for the second access. 

 

 

2.3 Header trace of requests from client

 

Here you can see the initial access to the /test/x resource, with 302 redirect to the main page 

siteminderagent/forms/splitStartFormLogin.fcc page 

 

Then when we click the "Gen Challenge" button on the page, via javascript we make two POST's to the backend.  The first generates the challenge and returns half the data as cookies, and the second call returns the second half of the data via cookies.  And the image is then put together and displayed. 

 

Here is the first response with cookies 1 and 2. : 

 

And here is the 2nd response with cookies 3 & 4. 

 

 

2.4 Considerations for Alternative Approaches 

 

Ideally we would like to get the value back as content rather than via a cookie - as returning as content it would be a "normal" GET operation to get an image resource.

 

If we had some programming ability at the webserver side, such as .net, or java then there would be some more options available to us to do that.  We could use the SSO SDK AgentAPI to bundle returned results into a response. 

 

Another alternative (with some webserver programming ability)  would be to have an initial auth level passed by the UN/PW of level = 1, which just allows access to resource that sets the data as headers, passed into the .jsp or .csharp page and then embeds the content into the page. 

 

Even with the extra large Set-Cookie command it is still sent back from the IIS webserver to the browser it is still actualy sent back from the IIS webserver, and the "Set-Cookie" command is then ignored by the web browser.  So some more tinkering with the javascript (perhaps using fetch) may have given access to the raw response set-cookie header.   Also some module running in the IIS webserver might have been able to split this up and recraft it as either many Set-Cookies or even embed it as content. 

 

If the request was going through CA SSO Access Gateway we might have been able to craft some httpd.conf mod_header commands to split it or re-craft it as content. 

 

.fcc pages can access headers (using smheaders directive) and you can set headers through on OnAuthChallenge - but in testing .fcc pages can only access headers set prior to the webagent, and headers set by the webagent are not visible. 

 

 

Another option may have been to return the data as part of the redirect URL from the custom auth scheme, and pick that up via javascript.  But that would have required use of fetch() rather than XMLPostRequest() which automatically follows the redirects. 

 

Unfortunately we were limited to .fcc processing on the webserver, so we had to go with the tools we had.  

 

There are some more notes about alternative solutions in the Solution Detail section. 

 

3 Client Side of the Solution 

Below is more detail about the custom .fcc pages and the main javascript functions that were used.

 

3.1 Main  functions in splitStartFormLogin.fcc page 

 

We added an extra button onto the starting login.fcc page : 

When pressed it calls the "genChallenge" method.

 

The genChallenge method sets the a targetURL to "/splitaith/genChallenge" and posts request to a splitAuthApiGenChallenge.fcc page (It is the targetURL + smagentname that drives which custom auth scheme is called and which responses are triggered, not the actual .fcc page name).   If we get a response, we collect the first two cookies, and then call "get2ndPart" function to get the 2nd part of the response. 

Note: The actual content of the splitAuthApiGenChallenge.fcc page does not matter too much, since we do not actually use it, we just want to trigger the OnChallenge response, and then read the generated cookie values. 

 

The "get2ndPart" function  sets up the targetURL as /splitauth/getPart" makes a call to a splitAuthApiGetPart.fcc 

And if we get a response we collect the two remaining cookies and call "showImage" to build and show the image.

 

The showImage function combines the cookie values, builds the image and appends it to the page. 

Note: We were lazy, when passing data via the cookies we needed to ensure there were not special characters.  The ";" is a special character for set-cookie and so if we passed the prologue 'data:image/jpeg;base64' via the cookie we would have to have encoded it somehow.  That's not hard but since the main bulk of the data was already base64 encoded, we just sent that and hardcoded prefix.

 

3.2 Supporting functions in splitStartFormLogin.fcc page 

The postFccPage() function, sets up the POST to the passed in .fcc page, with the passed in target.  The UN/PW and smagentname parameters taken from the current form page. 

The callback function is called when a response is received. 

Note: Maybe we could have used GET rather than POST, and sent in the Basic Authentiction: header.  I believe it would have worked, I did a quick trial for basic auth, before moving to the POST one, it failed, but I expect if we had set the SMCHALLENGE cookie to YES then that should work - if so that may be a slightly simpler approach.  

 

Note2: encodeURIComponent() was needed rather than encodeURI() call, most web samples give the encodeURI() method as the one to use, but our webagent needed the encodeURIComponent, which encodes a few more characters, if encodeURI was used the SSO webagent would return an error.

 

 

The getAndDeleteCookie() function, appends the cookie value to a list then deletes it from the page. 

Note: since these are large cookies we want to delete them fairly quickly so we don't keep sending larger data Cookie: headers back to the webserver.

 

 

4. CA SSO Policy Server Setup  

4.1 Authentication Schemes 

 

Only three are of interest. SplitAuthApiStartForm, SplitAuthApiGenChallenge, and SplitauthApiRunChallenge. 

Note: the forth one SplitAuthApiGetPart, is hangover from when we were returning parts as SMUSRMSG cookies 

 

SplitAuthApiStartForm - the purpose of this auth scheme is to do a normal redirect from the protected resource to the login page that has the special button, and javascript functions.  

 

SplitAuthApiGenChallenge - the purpose of this custom auth scheme is to validate the UN/PW auth;  then generate an image and store it against the user in the user store; then return a challenge status. the actual cookie values are returned as response attributes. 

 

SplitAuthApiRunChallenge - this auth scheme validates the UN/PW and then returns a challenge status, it is used to trigger the response, where the remaining two cookies are returned. 

 

 

4.2 Protected Realms 

The realms of interest are /test1/ /splitauth/getPart and /splitauth/genChallenge

For each of the realms, we have a basic rule that identifies any OnAuthChallenge made to that realm.

The Authentication Scheme varies, but is fairly simple to workout which one is used for which realm (and can see the package attached at the end of this document). 

 

OnAuthChallenge rule is pretty simple - matching all resources. 

 

 

4.3 Responses 

We have four responses, once for each "Part" of the image.  We are using 3k "parts" so the longer the image the more parts and response would be needed. 

 

We also have two Group responses, merging the parts 1&2 and 3&4 for our return pages.

 

SplitAuthResponse_PartX - each response is a call to the same ActiveResponseExample active response java code - they just pass in a different parameter to indicate which "part" to extract.

 

Details of the Set Cookie - only the name and the parameter are different in each one.

 

4.4 SSO Policy 

 

The Policy is also fairly simple, mainly we let all users access, only the responses are slightly tricky. 

 

We allow all users to access.

 

For the responses, the important ones are, /splitauth/genChallenge and /splitauth/getPart  these are the ones that we have the specific set-cookie responses. 

 

 

5 SSO Policy Server Custom Code 

 

5.1 Custom Auth Code - SplitAuthApiGenChallenge - generate and save the image  

 

For this java custom auth scheme, we have the main authenticate() method 

 

Here you can see the .setUserText() where we would normally have set a value for the SMUSRMSG cookie. 

But we are calling saveChallengeImage() and then returning status of SMAUTH_CHALLENGE. 

 

The saveChallengeImage() in our example saves a hardcoded static image, but for the client the image was a generated image : 

 

5.2 Custom Auth Code - SplitAuthApiRunChallenge - return challenge response.  

 

This auth scheme is similar to the last one, but just returns a challenge status, and does not regenerate the image. 

 

 

5.3 Custom Active Expression Code - ActiveResponseSample to retrieve part of image 

 

The ActiveExpression is started via an invoke call.   Here we parse an integer parameter, which we use to identify the segment number we want to return. 

 

getQRSegmentForUser() gets the generated image we have saves against the user, and we return the asked for segment of that.

getProp needs a max size, so we went with 16k.  After getting the attribute we get the segment we want for it.

 

getSegment() - the code for "getSegment" is included in the code bundle.  If set to segment 0 it will return the whole blob.  If the segment num is outside the range then it will return an empty string. 

 

 

6 Building and running custom code. 

6.1 Building custom auth and active expression.

 

The basic custom auth package is build using demo auth scheme I have.   

 

  • In the javaauthapi-splitauth.zip is the source code for the auth schemes and the active express.  And a build.bat file.

    You need to edit the build.bat file to point to the correct version of java, and then run it.  It will build a .jar file in the current directory.

    Then as described in the documentation in that directory you need to edit the JVMOptions.txt file to include the new .jar file. 

  • In the splitauthexport.xml are the xpsexport of the auth schemes used in this demo and the splitAuthDomain domain. You can either import those via xpsimport, or use them as a template to create your own (perhaps view them with the SMPolicyReader tool SMPolicyReader - tool to read smdif and XPS policy exports ) 

  • The fcc-pages.zip contains the fcc pages - you will need to deploy them onto the webagent.

 

 

6.2  Test Hint - Running Policy Server from the command line.

For ease of testing I am running the policy server from the DOS command line - you can do this on linux as well.

 

That makes it easy to see the simple System.out.println() type debugging that I've used in the SSO custom java components.

for example.,:

 

7.  Also Working with fcccompatmode=Yes 

A requirement we could not change was fcccompatmode=yes, the rest of this document describes the setup and operation with fcccompatmode=no.  But the same does work with fcccompatmode=yes - albeit that the POST results in a FORMCRED cookie and then 302 redirect to protected resource, where the FORMCRED is evaluated and the cookies are then set.  So a bit longer process but the same outcome. 

 

 

Hope you find this helpful.

 

Ok, I think that is everything, but I am sure I have left something out, or made a mistake if so then send me an email or add a reply to this community article.  

 

Cheers - Mark

Statistics
0 Favorited
5 Views
3 Files
0 Shares
1 Downloads
Attachment(s)
zip file
fcc-pages.zip   18 KB   1 version
Uploaded - May 29, 2019
zip file
javaauthapi-splitauth.zip   163 KB   1 version
Uploaded - May 29, 2019
zip file
splitauthexport.xml.zip   5 KB   1 version
Uploaded - May 29, 2019

Related Entries and Links

No Related Resource entered.