Understanding (and extending) UAG Web SSO capabilities

First of all, I would like to thank Matthieu Martineau (matthieu.martineau@piservices.fr) (Gold Partner, MCSE and MCT) with whom I had the opportunity to investigate some of the breaking scenarios I mention at the end of this post

In the wide range of services you get when publishing Web application with UAG, we have the ability to ask the product to provide Web Single Sign On. This is usually the feature that the end users like the most (versus security or strong authentication).

UAG SSO : introduction

UAG sits between the user and all published applications. So UAG has the ability to detect an authentication request sent back by the published application, and reply on behalf of the user, providing Web SSO experience (Heavy client SSO is not supported by UAG). All the “magic” of SSO with UAG do not take place on the client side (compared with E-SSO solution that require an agent installed on the client machine, and a way to gather the login/password before injection), but within the UAG machine itself. This is why it requires no “SSO agent” to be installed on the client machine and why UAG can provide Web SSO even if the machine is non-managed one (Partners, customers, … kiosk, home PC, ..).

When a user clicks an application in the portal (technically it generates an HTTP GET from the client towards the gateway), UAG process this request doing his job of reverse proxy by sending a similar HTTP GET (request towards the internal Web Application, on behalf of the user). Then if this Web application requires authentication, it will reply with an “authentication required” kind of message.

There are 2 type of “authentication required message”, depending on the configuration set on the Web application:

1) Form authentication: If the application is configured to request authentication via a Web FORM, it will just send back this FORM to the client machine. User will have to fill out this page with his login and password, and click the “connect” button.

2) Integrated authentication: If this application is configure as “integrated authentication” , this means that the client machine has to send again that HTTP GET message with an NTLM or Kerberos ticket (located in the HTTP header, in a variable name authorization) to this application. Technically speaking, the published application will reply with a HTTP 401 error message called “authentication required”, and part of this answer will contain what kind of supported authentication mechanism, NTLM and/or Kerberos.

UAG has the ability to handle both of them.

Integrated “401”

When you authenticated UAG, you provide your login and password. UAG kept that information in your user context (not stored anywhere just kept in memory for the session duration) so has the ability to re-use that information.

Based on the answer of the application (part of the), UAG will select the appropriate method for authentication (NTLM/Kerb),will call Windows API to get this token/ticket by providing the user’s login name and password, and get in return the “identifier”.

Then, once this “identifier” is generated, UAG will send again an HTTP GET, but this time the Header will have a new field called ”authorization” which contains the requested information.

FORM authentication

It is extremely easy to detect an authentication request if the application is using integrated. It will always send an HTTP 401 answer.

But if the published application is using FORM, it is a bit more complex. Why ? Because we need to detect that the HTML sent by the application is “THE” authentication page in order to do the Web SSO job. Since there is no equivalent to this 401 error, we will need to help UAG a little bit to do so.

To make this WEB SSO work, we will need to explain how structured is the authentication page for “THIS” particular application. To do so, we will tell UAG:

· Step 1: What is the URL to reach this authentication page : as soon as UAG sees a GET on that page, UAG knows that the page is an authentication FORM, it will start to work.

· Step 2 : We will tell UAG what is the name of the FORM itself. UAG will make sure that the HTML sent back is really the authentication page, my checking the “FORM” section of the page.

· Step 3 : we will tell UAG what is the name of the login field, and also what is the name of the password field

· Step 4 : we will tell UAG how to simulate the “click” on the page that will generated the authentication.

FORM authentication flow / UAG configuration

When you publish an application, the wizard shows you a list of application that UAG will support by default. This is because Microsoft engineers have already configured UAG to handle them. This is the notion of “optimizer”. If yours is not in the list, you will publish them via a Web Generic Template, and will have to tell UAG how to do the SSO.

Most of the configuration for SSO is done in a file names FORMLOGIN.XML.

This XML file will be used to tell UAG how to handle the “steps” we have described previously). Here is an example:

 

WHLFILTFORMLOGIN ver="1.0">

<APPLICATION>

               <APPLICATION_TYPE>AcmeAPP</APPLICATION_TYPE>

               <USAGE description="form_login">

               <PRIMARY_HOST_URL>.*login\.aspx.*</PRIMARY_HOST_URL>

               <SCRIPT_NAME source="file">Autosubmit_GTAC.js</SCRIPT_NAME>

               <USER_AGENT>

                      <AGENT_TYPE search="group">all_supported</AGENT_TYPE>

                      <POLICY>multiplatform</POLICY>

                      <SCRIPT_NAME source="data_definition">FormLoginHandler</SCRIPT_NAME>

               </USER_AGENT>

               <MULTIPLE_LOGIN>true</MULTIPLE_LOGIN>

               <LOGIN_FORM>

                      <NAME>form1</NAME>

                      <METHOD>POST</METHOD>

                      <CONTROL handling="real_value">

                              <TYPE>PASSWORD</TYPE>

                              <NAME>Login1#Password</NAME>

                              <DEF_VALUE>sitepass</DEF_VALUE>

                      </CONTROL>

                      <CONTROL handling="real_value">

                              <TYPE>USER_NAME</TYPE>

 

                              <NAME>Login1#UserName</NAME>

                              <DEF_VALUE>siteuser</DEF_VALUE>

                      </CONTROL>

                      <CONTROL handling="real_value">

                              <TYPE>submit</TYPE>

                              <NAME>Login1#LoginButton</NAME>

                              <DEF_VALUE>Connect</DEF_VALUE>

                      </CONTROL>

                      <LOGIN_EVALUATOR indicate="failure">

                              <SEARCH encoding="">Nom d'utilisateur ou mot de passe incorrect</SEARCH>

                      </LOGIN_EVALUATOR>

               </LOGIN_FORM>

               </USAGE>

       </APPLICATION>

       </WHLFILTFORMLOGIN>

In this example we have published an application with type “equal to AcmeApp”. This means that this configuration will only be used by application using such type (part of the wizard when you publish an application, and use the Generic Web Template, you have to specify a type).

Step 1 is to define the “URL” to reach that login form, so UAG will react on it. This is done by this line : <PRIMARY_HOST_URL>.*login\.aspx.*</PRIMARY_HOST_URL>. We use Regular Expression (Regex) for this, which means here “any URL that has ‘Login.aspx’”

Step 2 is to specify the name of the “FORM” (maybe that login.aspx page is used for many features, one of them is authentication.. so we also do that FORM name check). You do so by just checking the HTML source of the page, and then search the FORM Section. Identify the name, and set the configuration here : <NAME>form1</NAME>. In this scenario, the FORM name of the application is “FORM1”.

Step 3 is to specify the login and password field. This is done in this section:

 

<NAME>form1</NAME>

                      <METHOD>POST</METHOD>

                      <CONTROL handling="real_value">

                              <TYPE>PASSWORD</TYPE>

                              <NAME>Login1#Password</NAME>

                              <DEF_VALUE>sitepass</DEF_VALUE>

                      </CONTROL>

                      <CONTROL handling="real_value">

                              <TYPE>USER_NAME</TYPE>

                              <NAME>Login1#UserName</NAME>

                              <DEF_VALUE>siteuser</DEF_VALUE>

                      </CONTROL>

                      <CONTROL handling="real_value">

                              <TYPE>submit</TYPE>

                              <NAME>Login1#LoginButton</NAME>

                              <DEF_VALUE>Connect</DEF_VALUE>

                      </CONTROL>                   

 

Step 4 is to tell UAG how to “click” the connect button. This is done by injecting a javascript in the page that will autoexecute as soon as the page is displayed on the client machine. Usually the default javascript provided by UAG works fine. Default configuration is this : <SCRIPT_NAME source=" ">Autosubmit.js</SCRIPT_NAME>.

Step4 (optional, check end of this blog post for more details) : Sometimes the “click” do not work. To fix the problem you need to create your own “click” script. In this case parameter will be like this : <SCRIPT_NAME source="file">Autosubmit_AcmeApp.js</SCRIPT_NAME>.

This “JS” file has to be copied in this directory C:\Program Files\Microsoft Forefront Unified Access Gateway\von\Conf\WebSites\<Trunk name>\conf

Now that FormLogin.xml file is ready, copy it in the following directory: C:\Program Files\Microsoft Forefront Unified Access Gateway\von\Conf\WizardDefaults\FormLogin\CustomUpdate. Activate your configuration and it should work great

 “The click”, how it works

In the formlogin.xml, you have specified the <SCRIPT_NAME source=""> tag that tells UAG what script to inject in order to generate that “click” automatically.

When UAG will see that FORM coming from the published web server, it will add this script in the HTML, and send it back to the client. If you then check then the HTML you get on the client, you will see this:

 

<html>

<head>

 <title>Welcome on my application</title>

 <base href="https://portail.Company.com/uniquesig2a9bd5c4508d2/uniquesig0/application/">

<link rel="stylesheet" type="text/css" href="skins/application/css/global.css"></link>

</head>

<SCRIPT language="JavaScript">

function FormLoginSubmit()

{

       document.forms[1].submit();

       return false;

}

</SCRIPT>

<script language="javascript" src="tools/core.js"></script>

<script language="javascript" src="tools/tip.js"></script>

<script language="javascript" src="tools/datePicker.js"></script>

<script language="javascript" src="tools/menu.js"></script>

. . .                                        

 

Once this page arrives on the client machine, the browser will render the HTML, and will execute automatically this function. In this configuration it generates a “submit” on the FORM. In most of the cases that basic “document.forms[1].submit();” is sufficient to simulate a user click.

 

The script is here, is executed, but WEB SSO fails.

This is extremely rare, but sometimes this “submit” function do not generate what we expect. It is executed for sure, but the result is not the “click” we wanted to simulate.

The reason for this is the structure of the FORM itself. For a reason we cannot predict (the page is the result of the work of a man, so by definition it is not predictable), this submit message sent to the page is not working, probably arriving on an object in this page that is not our “connect” button.

Since it is not “predictable” we will need to edit and analyze the structure of the HTML page. Most of the time this HTML page contains Javascript (or Javascript on top of Javascript Framework) that in fact are causing the problem.

This is rare, but the methodology is then to “understand” how it works, prior to “tell” UAG what to do in order to get what we want.

The case of the failing WebSSO authentication: generic example

Again, since it is not “predictable” this example is just an “example” of a problem, and how to fix it.

In this scenario, Web SSO did not work. The page was correctly detected by UAG (step 1 of the configuration), the login/password field were correctly filled out (step 2 and 3), and our javascript was there (step 4).

But SSO was not working at all.

After investigation, we have detected that due to the structure of the page, the “object” receiving the “submit” message was not in fact the “Connect” button, which explains the failure. By looking at this HTML, we have identified also that this “Connect” button is calling a javascript function to do the authentication. Usually the FORM itself generate a POST with the parameters, for that application, the authentication was done by a javascript function named “Logon()”.

Now that we understand the problem, we just need to create our own JS .. with this code :

 

Default one

For this application

function FormLoginSubmit()

{

            document.forms[1].submit();

            return false;

}

 

function FormLoginSubmit()

{

            logon();

            //document.forms[1].submit();

            return false;

}

 

We created this JS file on UAG machine, saved it as “Autosubmit_GTAC.js”, and changed the FORMLOGIN.XML configuration appropriately. After activation this new JS is injected in the page, and it works.

Conclusion

In most of the case, UAG can handle itself the WebSSO mechanism. It is very rare that it fails, but due to the fact that more and more applications use Javascript (and Javascript on JS framework) we may encounter this situation.

UAG has all the mechanism to fix the problem, you just need to analyze the problem.. and once you know it, tell UAG how to fix it.

If this is the first time you encounter the problem, do not hesitate to ask assistance to partners and even Microsoft. First experience is always complex, next one is always “clear”.