Skip to content

Instantly share code, notes, and snippets.

@paully21
Created February 26, 2014 16:25
Show Gist options
  • Save paully21/9232979 to your computer and use it in GitHub Desktop.
Save paully21/9232979 to your computer and use it in GitHub Desktop.
ASP.NET MVC Discourse SSO Example
public ActionResult DiscourseLogin()
{
if (string.IsNullOrEmpty(Request.QueryString["sso"]) || string.IsNullOrEmpty(Request.QueryString["sig"]))
return Content("Invalid");
string ssoSecret = "YOUR SSO SECRET"; //must match sso_secret in discourse settings
string sso = Request.QueryString["sso"];
string sig = Request.QueryString["sig"];
string checksum = getHash(sso, ssoSecret);
if (checksum != sig)
return Content("Invalid");
byte[] ssoBytes = Convert.FromBase64String(sso);
string decodedSso = Encoding.UTF8.GetString(ssoBytes);
NameValueCollection nvc = HttpUtility.ParseQueryString(decodedSso);
string nonce = nvc["nonce"];
//TODO: Add your own get user information
//Ensure user is logged in by adding the [Authorize]
//Attribute to this controller method and validate the
//user has permission to access the forum
string email = "testuser@test.com";
string username = "testuser";
string name = "Test User";
string externalId = "21";
string returnPayload = "nonce=" + Server.UrlEncode(nonce) +
"&email=" + Server.UrlEncode(email) +
"&external_id=" + Server.UrlEncode(externalId) +
"&username=" + Server.UrlEncode(username) +
"&name=" + Server.UrlEncode(name);
string encodedPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(returnPayload));
string returnSig = getHash(encodedPayload, ssoSecret);
string redirectUrl = ConfigurationManager.AppSettings["DiscourseUrl"] + "/session/sso_login?sso=" + encodedPayload + "&sig=" + returnSig;
return Redirect(redirectUrl);
}
public string getHash(string payload, string ssoSecret)
{
var encoding = new System.Text.UTF8Encoding();
byte[] keyBytes = encoding.GetBytes(ssoSecret);
System.Security.Cryptography.HMACSHA256 hasher = new System.Security.Cryptography.HMACSHA256(keyBytes);
byte[] bytes = encoding.GetBytes(payload);
byte[] hash = hasher.ComputeHash(bytes);
string ret = string.Empty;
foreach (byte x in hash)
ret += String.Format("{0:x2}", x);
return ret;
}
@mahendruankit
Copy link

Thank you for posting the controller methods. This has been very helpful! Much appreciated.

@jlkalberer
Copy link

Does the externalId need to be an integer? I'm using EF Identity and all my IDs are GUID.

@scorchen
Copy link

Thanks for posting

@crpietschmann
Copy link

I know this is was posted YEARS ago, but thanks for sharing it. You'e saved me lots of time integrating Discourse SSO with an ASP.NET MVC application.

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