Implementing SSO, nonce immediately expires

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
https://meta.discourse.org/t/how-to-avoid-account-login-timed-out-please-try-logging-in-again-when-the-payload-had-expired-in-sso/35682/9?u=dim_taburetkin

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?

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

5 Likes

I’m still having this issue. Can you show me how you create your payload? I am trying to create it in Javascript. thanks