Probleme mit SSO und dem '~'-Zeichen

Hallo zusammen,

Ich habe kürzlich festgestellt, dass, wenn ich ‘~’ in die Biografien eines Benutzers aufnehme, ich einen base64decode-Fehler von Discourse erhalte. Es kann alle möglichen anderen problematischen Zeichen problemlos verarbeiten (Leerzeichen, =, %, &), aber aus irgendeinem Grund nicht ~.

Ist jemandem dieses Problem schon einmal begegnet?

Mein erster Gedanke ist, dass meine Kodierung falsch sein könnte, aber ich konnte es bisher nicht herausfinden.

Hier ist meine Python-Implementierung der Kodierung:

return_payload = base64.urlsafe_b64encode(parse.urlencode(params).encode())

die dann direkt in ‘sso’ in den Anfragen (zusammen mit allen anderen notwendigen Informationen) eingefügt wird

resp = requests.post(
       ".../admin/users/sync_sso",
        data={'sso': return_payload, ...}
        headers={...}
)

Ich habe mein Discourse auf die neueste Version (3.5.0.beta1-dev) aktualisiert, das Problem besteht weiterhin.

Vielen Dank für jede Hilfe!

Es sollte wahrscheinlich behoben sein, aber diese Frage übersteigt meine Zuständigkeit und meine Fähigkeiten. Aber aus rein praktischer Neugier: Warum sollte jemand eine Tilde in einer Biografie verwenden?

Heh, das ist wohl eine vernünftige Frage.

Ich betreibe ein mehrsprachiges Forum und in anderen Kulturen wird das ‘~’ häufig verwendet. Zum Beispiel wird es im Koreanischen oft am Ende verwendet, um den Ton abzuschwächen, wie zum Beispiel: „Wenn Sie Fragen haben, lassen Sie es mich wissen~“

Ist das also ein Fehlerbericht und keine Supportanfrage?

Ist es das? Ein Fehler ist etwas, das getan wird, aber nicht funktioniert. Dies ist eher eine Frage „Ist es fertig oder nicht?“ und dann ist es eher Feature, wenn es keine Support-Frage ist.

Ja, ich denke, Bug ist angemessen. Ich glaube, ich kodere es korrekt in Base64, sodass Discourse es auch korrekt dekodieren sollte.

Ich denke, es ist ein Fehler (vorausgesetzt, wir können ihn reproduzieren)

Es sieht so aus, als ob urlsafe_b64encode einige Zeichen in der Base64-Kodierung ersetzt. Aus der Dokumentation:

Kodiert bytes-ähnliches Objekt s unter Verwendung des URL- und Dateisystem-sicheren Alphabets, das - anstelle von + und _ anstelle von / im Standard-Base64-Alphabet ersetzt und gibt die kodierten bytes zurück. Das Ergebnis kann immer noch = enthalten.

Das bedeutet, dass das Ergebnis kein Standard-Base64 ist und nicht mit Discoures Dekodierung kompatibel ist.

Ich empfehle stattdessen die Verwendung der normalen b64encode-Funktion. Ihre HTTP-Bibliothek sollte sich bei Bedarf um das URL-Escaping kümmern.

Nach weiteren Nachforschungen habe ich es tatsächlich falsch kodiert.

Hier ist, was ich am Ende für die Nachwelt hatte:

return_payload = base64.b64encode(parse.urlencode(kwargs).encode("utf-8"))
h = hmac.new(secret.encode("utf-8"), return_payload, digestmod=hashlib.sha256)
resp = requests.post(
       ".../admin/users/sync_sso",
        data={"sso": return_payload, "sig": h.hexdigest()}
        headers={...}
)

Und wenn Sie die Weiterleitung durchführen, stellen Sie sicher, dass Sie diese {“sso”…} mit parse.urlencode kodieren.

Vielen Dank für die Hilfe @sam und @david!