Implementierung von SSO, Nonce läuft sofort ab

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

Ich habe immer noch dieses Problem. Können Sie mir zeigen, wie Sie Ihre Payload erstellen? Ich versuche, sie in JavaScript zu erstellen. Danke.