Implementing SSO, nonce immediately expires


(Dim Averyanov) #1

Hi, i am only trying to implement SSO.

Every time i redirect browser to “/session/sso_login?<…>” i see this error:
Account login timed out.

here is my workflow:

  1. user open discourse forum at http://forum.mysite.com and get auto redirect to sso end point http://mysite.com/sso?sso=…&sig=…
  2. http://mysite.com/sso backend takes sso param from querystring, validate it against sig param and if validation success unpack it urldecode(frombase64(urldecode(sso))) and store nonce value.
  3. http://mysite.com/sso backend create test payload with test user {nonce=storednonce,external_id=mytestid, email=myvalidemail}
  4. convert payload to sso param: sso = urlencode(base64(urlencode(payload)))
  5. create sig param as sig = hmacsha256(sso)
  6. send browser to http://forum.mysite.com/session/sso_login?sso=…&sig=…

but i always get error: Account login time out

i’ve searched topic about sso and find this

it seems that i can see this error even if my nonce is not correct at all.
so i’ve checked that i send back to discourse nonce i exactly receive.
same result.

there is no change if i do it immediately after receiving nonce or after some time in range of ten minutes
same result

what i am missing?
does discourse check if http://mysite.com/sso realy exist in the web?


(Dim Averyanov) #2

Solved.

My mistake was in preparing payload for redirect back to discourse
so nonce did not pass validation at the /session/sso_login
but the reason phrase is “nonce expired”.

my wrong method:

payload = "{nonce=aaaabbb&external_id=blablabla...}";
encoded = urlencode(payload); // <- mistake because of '=' replaced with encoded equivalent,
base64 = toBase64(encoded);
sig = hmac(base64);

correct method:

payload = "{nonce=aaabbb,external_id=[urlencoded value],...}; //encoded values instead of encoded whole string
base64 = toBase64(payload);
sig = hmac(base64)
sso = urlencode(base64)

and finaly sso and sig goes to querystring