How to Save Web Interface Usernames in a Cookie

In the article titled “How to Enable AutoComplete for Web Interface Logon”, I explained how to enable the AutoComplete functionality of web browsers in order to save usernames and/or passwords for Citrix Web Interface. As the article explained, there are a lot of moving parts to the solution such as web browser settings, Protected Storage, JavaScript workarounds, etc. In this article, I will explain how to accomplish something similar by using cookies to remember the last username entered for Web Interface.

In the article titled “How to Enable AutoComplete for Web Interface Logon”, I explained how to enable the AutoComplete functionality of web browsers in order to save usernames and/or passwords for Citrix Web Interface. As the article explained, there are a lot of moving parts to the solution such as web browser settings, Protected Storage, JavaScript workarounds, etc. In this article, I will explain how to accomplish something similar by using cookies to remember the last username entered for Web Interface.

How it Works (if you do not really care how it works, you can just download the modification at the end of this post)

There are really only two parts to this solution. Part 1 – store the username in a cookie. Part 2 – get the username from the cookie and populate the “user name” field at logon. There is a little Web Interface SDK work to obtain the username, but I will explain what is going on.

 

Part 1 – Storing the Username in a Cookie

There are two steps to accomplish this part.

First, we need to get the username after it is validated by Web Interface. An ideal place to get the authenticated username is applistView.ascx. applistView.ascx is the user control in Web Interface that is responsible for displaying a list of applications a user has access to. So, we know if we got to applistView.ascx in the Web Interface logon/application enumeration process that a username should be available.

Second, we need to store the username in a cookie (this is pretty easy in comparison to getting the username).

Here is the code:

Modify applistView.ascx

Find the following text (around line 10):

<!–#include file=”../serverscripts/include.aspxf”–>

Paste the following right after this line

<%

//----------------------------------------------------------------
// WI mod
//----------------------------------------------------------------

string username = String.Empty;

// Get username
com.citrix.authentication.tokens.AccessToken accessToken = com.citrix.wi.pageutils.Authentication.authGetPrimaryAccessToken(wiContext.getWebAbstraction());
if(accessToken != null)
{
if(accessToken is com.citrix.authentication.tokens.GuestToken)
{
// Guest
username = wiContext.getString("Guest");
}
else
{
username = accessToken.getUserIdentity();
}
}

HttpCookie userCookie = Request.Cookies.Get("WI_username");

if(userCookie == null)
{
// Cookie doesn't exist, so create it
userCookie = new HttpCookie("WI_username");
}
else if(userCookie.Value != username)
{
// Need to update the cookie value
Response.Cookies.Set(Request.Cookies.Get("WI_username"));
}

userCookie.Value = username;
userCookie.Expires = DateTime.Now.AddDays(100);
Response.Cookies.Add(userCookie);

//----------------------------------------------------------------
// End WI mod
//----------------------------------------------------------------

%>

Code explanation:

First, we need to get an AccessToken (see line 10 above). In the Web Interface object model, an AccessToken “…encapsulates information that may be used for authorization and authentication when a Subject requires access to a resource.” What that means in layman’s terms is an AcessToken basically holds your username, password, domain, identity, etc. (you can actually use the PasswordBasedToken Interface to get the password of a user if you wanted to as described in this article).

After we get the AccessToken, we can test to see if this is an anonymous user or not (an anonymous user would have a GuestToken) on lines 12-23 above. If the token is not a GuestToken, then we know we have an authenticated user. There are currently 3 methods you can use to get the user details from the AccessToken:

  1. getAccountIdentity() – gets an AccountIdentiy object.
  2. getShortUserName() – returns the username as a string. Example – if your user identity was domain\jasonco, getShortUserName() returns “jasonco”.
  3. getUserIdentity() – returns the entire logon identity as a string. Example: domain\username or user@domain (if using UPN). I chose getUserIdentity() in the code above.

The rest of the code is pretty straight forward – it just creates or updates the cookie named WI_username. You could actually name this cookie anything you wanted.

Part 2 – Retrieving/Populating the Username from the Cookie

This part is quite a bit easier than the first part. All we need to do is to get the cookie, if any, from the previous code and populate the username field on the log on screen. The logon screen code can be found in loginMainForm.inc.

Here is the code:

Modify loginMainForm.inc

Find the following text (around line 106):

<td colspan="2">
    <input type='text' name='<%=Constants.ID_USER%>' id='<%=Constants.ID_USER%>'
        class='loginEntries<%=viewControl.getExplicitDisabled()?" loginEntriesDisabled":""%>'
        maxlength='<%=Constants.LOGIN_ENTRY_MAX_LENGTH%>' <%=viewControl.getExplicitDisabledStr()%>
        tabindex='<%=Constants.TAB_INDEX_FORM%>'

Paste the following right after this text:

<%
//----------------------------------------------------------------
//       WI mod
//----------------------------------------------------------------

HttpCookie userCookie = Request.Cookies.Get("WI_username");

if(userCookie != null)
{
%>
    value='<%=userCookie.Value %>'
<%

}

//----------------------------------------------------------------
//       End WI mod
//----------------------------------------------------------------
%>

Code explanation:

The <input… tag above is the field where you fill in your username in loginMainForm.inc. The code inserted above sets the value of the input tag to whatever was stored in the WI_username cookie (if there was anything stored in the cookie at all).

If you want to implement this in your environment and do not feel like copying and pasting all this code, you can download the modified files below:

download Modification for Web Interface 5.1

Silverlight Web Interface Sneak Peak

What do you get when you combine Citrix Web Interface, Microsoft Silverlight, and AJAX? You get my latest Web Interface modification. Read on to find out more…

I have been preparing for some Citrix Synergy and BriForum sessions where I will be presenting on Web Interface internals and customizations. One of the customizations I put together is an adaptation of Narenda Wicaksono’s Silverlight TSWeb Access for Windows Server 2008 Terminal Services. I created a similar application built around the Citrix Web Interface API. I am using Microsoft Silverlight 2.0, AJAX, Web Interface APIs, and Citrix XenApp 4.5. Check out this short video to see more:

I know it was hard to tell a lot of details from the video, but I will post more details soon.

Template updates for Citrix Web Interface 4.6

Two of my most popular posts (“Super Easy Customization of Citrix Web Interface 4.x” and the “Citrix Web Interface SharePoint Look and Feel Template” download) have been updated to include support for Citrix Web Interface 4.6.

In preparing for some Citrix Synergy and BriForum sessions, I made some updates to the following two articles:

The Super Easy Customization of Citrix Web Interface 4.x article has been updated to include a “bare bones” template for Web Interface 4.6.

The Citrix Web Interface SharePoint Look and Feel Template download has been updated to include a SharePoint look and feel template for Web Interface 4.6.

Feel free to use/modify these templates for your own use.

Script to Manipulate APPSRV.INI

What happens when you need to make mass changes to APPSRV.INI? Use this script to make changes to your user’s APPSRV.INI file via login script. The script adds or modifies .INI file key/value pairs and sections.

Use this script to make changes to your user’s APPSRV.INI file via login script. The script adds or modifies .INI file key/value pairs and sections.

  Download mod_appsrv script v1.1

The Scenario
So, you have been combing through the various support forums all day long trying to find a solution for an issue. You finally find the solution, but it involves modifying every user’s APPSRV.INI file located on their workstation. One common solution that matches the above scenario has to do with Single Sign On issues with Citrix Web Interface. One of the most recommended solutions is to add the following two lines to the [WFClient] section of APPSRV.INI:

SSOnUserSetting=On
EnableSSOnThruICAFile=On

Reference: http://support.citrix.com/article/ctx368624

The Dilemma
So, you try this and it fixes the issue for the user. What do you do now? Manually modify each user’s APPSRV.INI? Tell your users to perform the modification themselves? Script the change? Tell your boss there is no fix for the issue?

The Solution
Script the change sounds good to me, but how do you do that? That is where this article comes in. I mentioned I had a script to manipulate APPSRV.INI in the comments of this article. I have received many emails requesting the script. So, I decided to “spruce up” the script a little by adding more comments and logging and then share it. The script is written in such a way that you can add or modify any key/value pair to any section in APPSRV.INI (or any .INI file for that matter). Just modify the following section of the script to suit your needs:

'**********************************************************
' Add/modify key/value pairs
' modINISection takes 3 parameters:
'    Section name
'    Key
'    Value
'**********************************************************
modINISection "WFClient", "SSOnUserSetting", "On"
modINISection "WFClient", "EnableSSOnThruICAFile", "On"

The above example shows how to implement the solution to the delimma discussed earlier.

Here is another useful one to add that addresses clipboard issues:

modINISection "WFClient", "CbChainInterval", "2000"

From the Citrix Client 9.100 Readme http://support.citrix.com/article/CTX107650

“This fix introduces support for a mechanism to check at periodic intervals the client’s ability to receive clipboard change notifications. If the mechanism finds the client to be unable to receive such notifications, the client will attempt to register itself to receive future notifications. To enable this functionality, you must modify users’ appsrv.ini files as follows: 1. Open the appsrv.ini file located in the user profile directory using a text editor. 2. In the WFClient section, locate or add the entry: CbChainInterval=<value>, where value is the interval, in milliseconds, at which checks are to be performed. Supported values range from 0 to 2,000, inclusive.”

Think of it as an auto RepairCDBChain.exe

Some quick things to note about the script:

  • If you specify a section for modINISection that does not exist, the section will be created.
  • If you specify a key that does not exist, the key will be created at the end of the section.
  • Curretnly, there is no implementation to delete key/value pairs (I’m not sure that would even be useful for the intended usage)
  • A log file is created in the same directory as the APPSRV.INI file. The log file is named the same as the script name. If you change the script name to match you company’s naming convetion, the log file name will change automatically.

Good luck and have fun. But, as always, test test test. Make sure this script works in your environment before you throw it out there on your global login script.

Citrix Access Gateway AAC 4.2 "SharePoint Look and Feel" Template

This download will help you change your ordinary Citrix Access Gateway with Advanced Access Control Logon Point into a SharePoint looking Logon Point.

This Citrix support article details basic customization of the Advanced Access Control 4.2 Logon Point.  I took this Citrix article and the Citrix Web Interface “SharePoint Look and Feel” Template to come up with a SharePoint look and feel for the Advanced Access Control 4.2 Citrix Access Gateway Logon Point.  Check out the before and after screen shots below:

Before:

Click to enlarge

After:

Click to enlarge

Citrix Access Gateway AAC 4.2 SharePoint Template

Super Easy Customization of Citrix Web Interface 4.x

UPDATED (now includes 4.2 template). There are several resources out there explaining how to customize or brand Citrix Web Interface. The easiest method I’ve found by far is to modify the layout.ascx user control. Using the technique outlined in this article, you can quickly give your Web Interface site a brand new look and feel.

There are several resources out there explaining how to customize, or brand, Citrix Web Interface. The easiest method I’ve found by far is to modify the layout.ascx user control. Using the technique outlined in this article, you can quickly give your Web Interface site a brand new look and feel.

The layout.ascx user control
The heart of the Web Interface layout is a file called layout.ascx. Layout.ascx is a user control that “constructs” the Web Interface authentication and applications page’s HTML. There are two different layout.ascx files for every Web Interface site. These layout.ascx files can be found at path_to_your_wi_site\auth\include (login page) and path_to_your_wi_site\site\include (applications page).

UPDATE: The layout.ascx files in Web Interface 4.6 are located at path_to_your_wi_site\app_data\auth\include (login page) and path_to_your_wi_site\app_data\site\include (applications page).

Cutting layout.ascx to the core
To get started, open up the layout.ascx file located at path_to_your_wi_site\site\include. Next, strip out all the markup and code between the opening and closing <body> tags except the <wi:Welcome runat=”server”/>, <wi:MessageCenter>, <wi:Toolbar>, and <asp:PlaceHolder> tags. These tags are the “meat and potatoes” of the Web Interface applications page. The <wi:Welcome runat=”server”/> tag displays the welcome message. The <wi:MessageCenter> tag displays the message center. The <wi:Toolbar> tag shows the toolbar holding the refresh, settings, and help buttons. The <asp:PlaceHolder> tag shows all the published applications for the authenticated user.

Note: it is not necessary to use any of these tags in your final markup although it would be pretty silly not to include at least the <asp:PlaceHolder> tag.

The end result should look something like this:

<body text="#000000" bgcolor="#FFFFFF" LINK="#000000" VLINK="#000000" ALINK="#000000" topmargin='0' leftmargin='0' marginheight="0" marginwidth="0" onLoad="onLoadLayout();" dir="<%=getString("TextDirection", currentLocale)%>">

<wi:Welcome runat="server"/>
<wi:MessageCenter runat="server"/>
<wi:Toolbar runat="server"/>
<asp:PlaceHolder id="ViewPlaceHolder" runat="server" />

</body>

This produces a “bare bones” Web Interface page.  Check it out:

Click to enlarge
Click to enlarge

If you would like a copy of this “bare bones” layout.ascx file, you can download it below:

layout_40.zip (for Web Interface 4.0)

layout_42.zip (for Web Interface 4.2)

layout_46.zip (for Web Interface 4.6)

Giving layout.ascx a facelift
Now, start adding your markup to the layout.ascx file and place the above mentioned tags where you want. If you want to modify text and color properties of the application links, the easiest place to do that would be the style.inc file located in the same place as the layout.ascx file. You can use this same technique for the layout.ascx file located at path_to_your_wi_site\auth\include to customize the login page.

Note: if you need to grab the username and password of the authenticated user, check out this article for instructions on how to do it.

Using the method described in this article, I made Citrix Web Interface look and feel like Microsoft SharePoint Portal Server 2003. Check it out below:

Citrix Web Interface with a Microsoft SharePoint look and feel
Click to enlarge

You may ask yourself, “Why would I ever want to do this?”.  Well, in this case the company was migrating from a custom written Intranet portal to Microsoft Office SharePoint Portal Server 2003 at the same time they were migrating from Citrix MetaFrame XP to Citrix Presentation Server 4.0.  The SharePoint migration would take place after the PS4 migration.  So, to minimize end-user impact, the custom portal was replaced with this SharePoint “fake-out”.  When the portal migration was ready, the front end never really looked that different to the end user, but the back end was vastly different.

If you would like a copy of the templates I used to make Web Interface look and feel like SharePoint, you can download them here

.