Skip to content

Instantly share code, notes, and snippets.

@42degrees
Forked from darkpssngr/sso_login_freshdesk.cs
Last active December 27, 2018 21:59
Show Gist options
  • Save 42degrees/0b8876b77005b51dc4bbe391cfa69670 to your computer and use it in GitHub Desktop.
Save 42degrees/0b8876b77005b51dc4bbe391cfa69670 to your computer and use it in GitHub Desktop.
SSO Login for Freshdesk support portal - ASP.Net C# Sample Code
/// <summary>
/// Handles the display of having successfully logged out of Freshdesk. There
/// are no other side-effects.
/// </summary>
public ActionResult FreshdeskLogout()
{
return View();
}
/// <summary>
/// Handles logging into FreshDesk with multiple products.
/// </summary>
/// <param name="host_url">
/// The host name of the "product" for which the user is requesting support.
/// Regardless of the parameter being called host_url it doesn't appear to ever contain a URL.
/// It's unclear if this parameter is passed if you are using a lower-tier version of FreshDesk.
/// </param>
/// <returns>A redirection to the proper URL for logging the current user into FreshDesk.</returns>
public ActionResult FreshDeskLogin(string host_url)
{
if (!Request.IsAuthenticated)
{
return RedirectToAction("Index", "Home");
}
var secret = System.Configuration.ConfigurationManager.AppSettings[@"freshdesk:SimpleSSOSecret"];
var defaultHostname = System.Configuration.ConfigurationManager.AppSettings[@"freshdesk:DefaultHostname"];
if (string.IsNullOrEmpty(secret) || string.IsNullOrEmpty(defaultHostname))
{
ViewBag.ErrorText = "Freshdesk configuration is missing or invalid";
return View();
}
var freshDeskPortalHostname = defaultHostname;
// Figure out which "product" of ours is trying to login, and send them back
if (null != host_url)
{
freshDeskPortalHostname = host_url;
}
var userService = new UserService();
var id = User.Identity as ClaimsIdentity;
var userNameTrimmed = id.Name.Trim();
var user = userService.GetUser(userNameTrimmed);
var name = $"{user.Firstname} {user.Lastname}";
var email = user.Membership.Email;
var timems = (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds.ToString();
// Get a hash signature that proves the request originated from a registered customer.
var hash = GetFreshdeskHash(secret, name, email, timems);
var path = $@"https://{freshDeskPortalHostname}/login/sso?name={Server.UrlEncode(name)
}&email={Server.UrlEncode(email)
}&timestamp={timems
}&hash={hash}";
return Redirect(path);
}
/// <summary>
/// Special hash required by FreshDesk to validate that the sender is an authorized user.
/// The parameters in the hash must also be available in the URL that is generated, plus
/// the one secret value assigned to a specific FreshDesk license.
/// </summary>
/// <param name="secret">A secret value (probably a GUID) provided by FreshDesk</param>
/// <param name="name">The name of the person logging in (for display).</param>
/// <param name="email">The e-mail address of the person logging in (for contact).</param>
/// <param name="timems">A time value that makes the block unique even for the same user.</param>
/// <returns>A hash "signature" for this login.</returns>
private static string GetFreshdeskHash(string secret, string name, string email, string timems)
{
var input = name + secret + email + timems;
var keybytes = Encoding.Default.GetBytes(secret);
var inputBytes = Encoding.Default.GetBytes(input);
var crypto = new HMACMD5(keybytes);
var hash = crypto.ComputeHash(inputBytes);
return hash.Select(b => b.ToString("x2"))
.Aggregate(new StringBuilder(),
(current, next) => current.Append(next),
current => current.ToString());
}
@KSDavids
Copy link

Is this for multiple domains or just multiple products?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment