I recently had a customer ask about how to do SSO with an email address and not the samAccountName. Knowing that Forefront Unified Access Gateway (UAG) is VERY flexible, the answer is of course yes, and this blog outlines how.
My customer has a need to hold non-employee accounts in their directory. Specifically, they use Active Directory (AD) for SharePoint. They have both employees and non-employees in the directory. Their challenge was to get the non-employees to remember their AD user id. The answer was to have the non-employee use their company email address, something they can remember.
While AD understands Universal Principal Name (UPN), it is not a free text field allowing you to type anything you choose. In addition, you cannot include a “@” in your samAccountName, as AD does not allow this.
UAG can be configured to do a lookup of the email address and return the samAccountName. This is no different than many LDAP login mechanisms, but the important thing is that UAG does know the real samAccountName, which is required to perform SSO login to most applications.
To enable UAG to do this “switch email for samAccountName” function we add a prevalidate.inc file, as discussed on page 99 of IAG_AdvancedUserGuide.pdf. (Note: IAG was the prior name for UAG).
For this demonstration, we will assume you already have SharePoint setup and protected by UAG. We assume that the user can log in successfully with their userid (samAccountName), we just want to add e-mail address support.
Step 1. Create the file <TrunkName><0 or 1>PreValidate.inc, where the TrunkName is the name you created in UAG, and 0 stand for HTTP and 1 stands for HTTPS. In my case, my trunk was named “UAG” and it was HTTPS, so my filename is UAG1PreValidate.inc. This file is placed in the \von\InternalSite\inc\CustomUpdate directory.
Step 2. Add code similar to the following in the file. Note you will need to change the userid and password (on the Ads Provider line) and LDAP string (on the oConn.Execute line) to match your settings. See security note below*.
If instr(Session("user_name"&num),"@") > 0 then
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.Provider = "ADSDSOObject"
oConn.Open "Ads Provider", "scd-labs\serviceaccount", "servicepassword"
Set rs = oConn.Execute("<LDAP://dc=SCD-LABS,dc=net>;(&(objectClass=user)(mail=" & Session("user_name"&num) & "));sAMAccountName")
if not rs.eof then
if rs.recordcount = 1 then ' we found our user!
Session("user_name"&num) = trim(rs("sAMAccountName").value) ' Required for SSO and change password
user_name = trim(rs("sAMAccountName").value) ' Required to pass CheckCredentials()
response.write "<font color=""red""><b><center>More than one user was found with the e-mail address " & Session("user_name"&num) & "<br></center></font></b>"
response.write "<font color=""red""><b><center>No user was found with the e-mail address " & Session("user_name"&num) & "<br></center></font></b>"
set oConn = nothing
set rs = nothing
Step 3. Activate the configuration.
Step 4. Create an account in Active Directory with a known email address.
Step 5. Log in using the email address as the account name and the real password.
If you have an error, and the UAG portal gives you an “Error 500”, then verify the code above, looking for any special characters that can be common in Unicode files.
*Security Note: Neither Microsoft or I are recommending having clear text passwords in text files on product servers. The goal of this blog was to show how it could be done in the simplest form. There are many ways to encrypt the password, but that is beyond the scope of this blog.
Thanks for the post. It is was straightforward and simple to implement.
Thanks! I'll let Yuri and Kevin know.
Is there any possibility to do this same converting to users that are using Outlook and then the traffic is Outlook Anywhere that reaches the trunk?
Is there anyway where it can accept other email ids associated to the users account for example gmail, hotmail. The above script only accepts the UPN of the joined DC. Kindly advice.
Are there any legal requirements which needs to be considered when asking a user to register using their email address as their user name instead of a fictional id of their choice?