Casifying TeamDynamix (TDNext)
We have recently implemented TeamDynamix at our campus. Here are my crude notes on how to accomplish authentication via CAS to TeamDynamix.
From their site:
The Only PPM Solution Designed For Higher Education. |
TeamDynamixHE provides the only project and portfolio management solutions specifically tailored to accommodate the needs of Higher Education. With a simple yet powerful interface, TeamDynamixHE solutions enable colleges and universities to prioritize efforts, adapt to change, manage resources and meet commitments on time and on budget. |
Notes:
- TeamDynamix has numerous web applications, at this time version 7.1 only has SSO support for the component TDNext.
- Since TeamDynamix uses Windows form authentication, the officail cas .Net client will not work. So we used the method explained here: ASP.NET Forms Authentication
- We are using .Net 4
- Cas Server 3.4.2
- TeamDynamix caches the authentication framework, so you will need to restart IIS for DLL changes to be loaded.
Step 1 configure TdNext's web.config to use Custom SSOAuth.
TeamDynamix has a hook for customSSO, that we must configure.
- Configure SSOReturnUrl
- Configure SSOLogoutUrl
- Switch the loginurl of authentication to *LoginSSO.aspx *from Login.aspx
Note, as usual with CAS, make sure to URLEncode the service URL.
<appSettings> .... <!--SSOReturnUrl: If you use a single sign on provider, set the "SSOReturnUrl" to the url for the single sign on provider. Also, set the <authentication> node LoginUrl to "LoginSSO.aspx"--> <add key="SSOReturnUrl" value="https://cas.myuniversity.edu/login?service=https%3A%2F%2Fdev-dynamix.myuniversity.edu%2FTDNext%2FLoginSSO.aspx%3FReturnUrl%3D%2FTDNext%2FHome%2FDesktop%2FDesktop.aspx" /> <!--SSOLogoutUrl: This is the url you want the users browser to go after logging out of TD. This is required for SSO implementations and optional for others--> <add key="SSOReturnUrl" value="https://cas.myuniversity.edu/login?service=https%3A%2F%2Fdynamix.myuniversity.edu%2FTDNext%2FLoginSSO.aspx%3FReturnUrl%3D%2FTDNext%2FHome%2FDesktop%2FDesktop.aspx" /> <!--SSOLogoutUrl: This is the url you want the users browser to go after logging out of TD. This is required for SSO implementations and optional for others--> <add key="SSOLogoutUrl" value="https://cas.myuniversity.edu/logout" /> .... </appSettings> .... <system.web> .... <authentication mode="Forms"> <forms name="TeamDynamix" loginUrl="LoginSSO.aspx" timeout="480" defaultUrl="LoginSSO.aspx" cookieless="UseCookies" slidingExpiration="true" path="/" protection="All"> <credentials passwordFormat="SHA1" /> </forms> </authentication> .... </system.web>
Step 2 create the .net dll (SSOAuth that overrides the TeamDynamix interface)
- Include the TeamDynamix SDK dll as a reference.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;
using System.IO;
using System.Net;
using System.Xml;
using System.Web.Security;
using System.Net.Security;
namespace TeamDynamixCAS
{
public class SSOAuth : TeamDynamix.AuthenticationSDK.IAuthenticationProvider
{
public String AuthenticationSso(System.Web.HttpRequest req)
{
//Set up dynamic switch for production/test
string CASHOST = "https://dev-cas.myuniversity.edu/";
string urlencodedService = "https%3A%2F%2Fdev-dynamix.myuniversity.edu%2FTDNext%2FLoginSSO.aspx";
if (req.ServerVariables["HTTP_HOST"].Equals("dynamix.myuniversity.edu"))//use production cas/dynamix settings.
{
CASHOST = "https://cas.myuniversity.edu/";
urlencodedService = "https%3A%2F%2Fdynamix.myuniversity.edu%2FTDNext%2FLoginSSO.aspx";
}
string tkt = req.QueryString["ticket"];
if (tkt != null && tkt.Length > 0)
{
string service = urlencodedService + "%3FReturnUrl%3D%2FTDNext%2FHome%2FDesktop%2FDesktop.aspx";
string validateurl = CASHOST + "serviceValidate?" + "ticket=" + tkt + "&" + "service=" + service;
StreamReader Reader = new StreamReader(new WebClient().OpenRead(validateurl));
string resp = Reader.ReadToEnd();
NameTable nt = new NameTable();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None);
XmlTextReader reader = new XmlTextReader(resp, XmlNodeType.Element, context);
while (reader.Read())
{
if (reader.IsStartElement())
{
string tag = reader.LocalName;
if (tag == "user")
return reader.ReadString();
}
}
reader.Close();
}
return "";//TD expects blank, as an indicator that the user is not logged in.
}
public bool Authenticate(string UserName, string Password)
{
return false;
}
public bool ChangePassword(string Username, string OldPassword, string NewPassword)
{
return false;
}
public bool SupportsChangePassword { get { return false; } }
}
}
Step 3 compile for release
- Move the release dll to the bin directory of TDnext/bin
- Restart IIS, since TeamDynamix caches various dlls.
