Problem with DotNetCasClient getting additional attributes from CAS-Server response

I’m usin CAS-JASIG server with Active Directory for authentication. But I found a problem with the DotNetCasClient-1.0.1. I was not able to retrieve the user parameters that CAS-Server send in the XML response after a success authentication.

I knew that my CAS-Server response was sending those parameters. Because my PHP-CAS Client applications read those parameters without any problem. In fact the response looks like this:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
 <cas:authenticationSuccess>
 <cas:user>janedoe</cas:user>
 <cas:attribute name="mail" value="janedoe@test.com" />
 <cas:attribute name="sn" value="Doe Doe" />
 <cas:attribute name="cn" value="Jane Doe" />
 <cas:attribute name="givenName" value="Jane" />
 </cas:authenticationSuccess>
 </cas:serviceResponse>

NOTE: To send additional user parameters from CAS-Server to CAS-Clients. You need to modify your “deployerConfigContext.xml”. Let me know if you are having problems whit LDAP configuration.

How did I note that DotnetCasClient was not retrieving those additional attributes? Well, from my own C# code when the user was successfully authenticated against CAS-Server I ask to DotnetCasClient for those additional attributes:

CasPrincipal tmpUser = (CasPrincipal)System.Web.HttpContext.Current.User;
if (tmpUser.Assertion.Attributes != null && tmpUser.Assertion.Attributes.Count > 0)
{

     //NEVER MET THIS CONDITION BECAUSE "tmpUser.Assertion.Attributes" WAS ALWAYS NULL

}

How did I solve my problem? Well, after debugging a lot I found out that It was not a configuration problem. That the problem came from the DotNetCasClient code. Because those attributes were never set. So I modified the “DotNetCasClient\Validation\TicketValidator\Cas20ServiceTicketValidator [Line 134] method ParseResponseFromServer” and add the following code :

if (authSuccessResponse.Proxies != null && authSuccessResponse.Proxies.Length > 0)</pre>
{
     :
     :
     //I didn't modified anything here!
     :
     :
     :
}
else
{
     /* HERE STARTS MY CHANGE */
     IDictionary<string, IList<string>> attributes =
               new Dictionary<string, IList<string>>();
     try
     {
          XmlDocument doc = new XmlDocument();
          doc.LoadXml(response);
          XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
          namespaceManager.AddNamespace("cas", "http://www.yale.edu/tp/cas");
          XmlNode GeneralInformationNode = doc.SelectSingleNode("/cas:serviceResponse/cas:authenticationSuccess/cas:attributes", namespaceManager);
          XmlNodeList attri = GeneralInformationNode.SelectNodes("cas:attribute",namespaceManager);

         if (attri != null)
         {
             foreach (XmlNode node in attri)
             {
                 XmlElement z = (XmlElement)node;

                 IList<string> values = new List<string>();
                 values.Add(z.GetAttribute("value").ToString());
                 attributes.Add(z.GetAttribute("name").ToString(), values);
             }
         }
         return new CasPrincipal(new Assertion(authSuccessResponse.User, attributes), proxyGrantingTicketIou);
    }
    catch (Exception e)
    {
        throw new TicketValidationException("CUSTOM CODE EXCEPTION["+e.Message+"]: "+e.StackTrace);
    }
    /* HERE ENDS MY CHANGE */

    //I didn't touch anything from here either
             :
             :
             :
             :
}

This is just I problem that I face with DotnetCasClient for this very specific case. I don’t know if is just me but I wanna share my solution (my way). Perhaps if you have a better one, please share 🙂