-
-
Save barryokane/2718191 to your computer and use it in GitHub Desktop.
protected void Page_Load(object sender, EventArgs e) | |
{ | |
string url = GetSsoUrl(ConfigurationManager.AppSettings["FreshDesk.BaseUrl"], //including trailing slash | |
ConfigurationManager.AppSettings["FreshDesk.Secert"], user.UserName, user.Email); | |
Response.Redirect(url); | |
} | |
string GetSsoUrl(string baseUrl, string secert, string name, string email) | |
{ | |
return String.Format("{0}login/sso/?name={1}&email={2}&hash={3}", baseUrl, Server.UrlEncode(name), | |
Server.UrlEncode(email), GetHash(secert, name, email)); | |
} | |
static string GetHash(string secert, string name, string email) | |
{ | |
string input = name + email + secert; | |
MD5 md5 = System.Security.Cryptography.MD5.Create(); | |
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input); | |
byte[] hash = md5.ComputeHash(inputBytes); | |
StringBuilder sb = new StringBuilder(); | |
foreach (byte b in hash) | |
{ | |
string hexValue = b.ToString("X").ToLower(); // Lowercase for compatibility on case-sensitive systems | |
sb.Append((hexValue.Length == 1 ? "0" : "") + hexValue); | |
} | |
return sb.ToString(); | |
} |
@42degrees a small bug in your code. you forgot to add timestamp in the string interpolation parameters for generating the url.
@barryokane can you please update the gist to reflect the new code ? (my fork with the fixed code https://gist.github.com/darkpssngr/726162ed0bd67ffdd616370c65a17e68 )
static string GetSsoUrl(string baseUrl, string secret, string name, string email) {
var timems = (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString();
return String.Format("{0}/login/sso?name={1}&email={2}×tamp={3}&hash={4}",
baseUrl, Server.UrlEncode(name), Server.UrlEncode(email), timems, GetHash(secret, name, email, timems));
}
private static string GetHash(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());
}
I've dropped Freshdesk an email to see how we can test etc. This all seems very rushed, so my guess is they are plugging a security hole, but right now we need a test rig to know if our implementations will work once they flick the Big Red Switch!
If we have a test rig, we can just see what works. Really appreciate the comments above, hopefully one of them is the solution.
Thanks @darkpssngr, fixed.
Well, they gave us a test environment by flicking the Big Red Switch and letting us test in a live environment whilst our users couldn't login! Nice.
I'm now up and running, borrowing code from above, but very slightly different. Just in case it helps anyone, but the harder work was done by those people above, not me!
I have timestamp in the return url, not tamp.
const string key = "XXXXXXXXXXXXXXXXXXXXXXX";
const string pathTemplate = "https://support.XXXX.com/login/sso?name={0}&email={1}×tamp={2}&hash={3}";
string timems = (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds.ToString();
var hash = GetHash(key, alias, tbEmail.Text, timems);
var path = String.Format(pathTemplate, Server.UrlEncode(alias), Server.UrlEncode(tbEmail.Text), timems, hash);
Response.Redirect(path);
Same GetHash as above:
private static string GetHash(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());
}
I had some Encoding trouble with European Culture and Special Characters.
Here is a "Global" working version of @GrahamEHughes Code.
There are two Changes:
- Usage of Encoding.UTF8 instead of Encoding.Default in GetHash
private static string GetHash(string secret, string name, string email, string timems)
{
var input = name + secret + email + timems;
var keybytes = Encoding.UTF8.GetBytes(secret);
var inputBytes = Encoding.UTF8.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());
}
- Change of datetime Calculation:
string timems = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
Some other comments on the code.
You are using the "X" as a format string for ToString() and then you are calling ToLower() when you could have just used "x" to get the lower-case hexadecimal value.
You are also then creating a leading zero in the loop, when you could have just used a format string "x2" (hexadecimal padded with leading zeroes to a minimum length of 2).
Here is some updated code (also adding the new hash and URL requirements):