Authentifizierungsprotokoll bzgl. App-Integration

Hey all! My team and I have been looking into possible ways to integrate our [future] Discourse instance into our mobile application - Noom. Our iOS app is written in Objective-C with some Swift, and our Android application is written in Java with some Kotlin. We’ve been debating between full integration via API or web view as our goal is an SSO flow where our users can seamlessly transition from an in-app experience to our Discourse instance.

I’m currently waiting on our QA team to get back to me on which authentication protocols we currently use, but I was curious as to anyone else’s experience integrating Discourse into a mobile application with or without SSO, and what methods (if any) you found most useful throughout the process. I’m aware of Discourse’s compatibility with OAuth/2, although not aware of other potential protocols.

My apologies if this is in the wrong category!

There is a new way of authentication. However the documentation is yet to be released.

I’m going to update the documentation about delegated authentication soon, but I can give you some pointers right here.

First you need to open a browser session to discourse.site/user-api-key/new with the following parameters:

scopes: 'notifications,session_info,one_time_password',
client_id: YOUR_APP_CLIENT_ID,
nonce: GENERATED_NONCE,
auth_redirect: YOUR_APP_URL_SCHEME,
application_name: YOUR_APP_NAME,
push_url: PUSH_URL (if you are going to send PNs from Discourse to your app),
public_key: PUBLIC_KEY (generated in your app)

You can have a look at the implementation of our DiscourseMobile app for details on the above but the main idea is that your app will launch a browser screen to the URL above, asking the user to authenticate to the Discourse site and authorize your app access to it. Once user authorizes access, Discourse will redirect to YOUR_APP_URL_SCHEME?payload= with an encrypted payload. You’ll need to set up your app to decrypt the payload and store the authToken. In iOS, you should use ASWebAuthenticationSession | Apple Developer Documentation (I don’t know if there is an Android equivalent).

Your authToken can make API requests limited by the scopes requested initially, for a full list of scopes, please look under allow user api key scopes in site settings.

The one_time_password scope allows the authToken to make a request for a one-time-password. The endpoint for this is /user-api-key/otp with the parameters auth_redirect, application_name and public_key.

I will write a proper documentation shortly, but this should help you get started.

@hosna + @pmusaraj Thank you both! I will pass this information along to our QA director.

@pmusaraj Hey, gibt es bereits eine offizielle Dokumentation, die der Öffentlichkeit zugänglich ist? Ich würde gerne tiefer einsteigen.

Ich werde mich in den nächsten Tagen genau damit befassen und über meinen Erfolg oder Misserfolg berichten. Falls jemand Anleitungen oder Tipps hat, würde ich mich sehr freuen, diese zu erhalten :slight_smile:

Ich glaube, Sie suchen nach User API keys specification und speziell dem Abschnitt „API-Schlüssel-Erstellungsablauf“.

Hey Penar, danke für die Anleitung. Ich bin in diesem Bereich noch kein Experte, habe bisher wenig mit Kryptografie oder solchen APIs gearbeitet und würde mich freuen, wenn du mir etwas Hilfe beim Kodieren einiger dieser Parameter geben könntest. Ich schaue mir deine DiscourseMobile-App an, habe aber noch nie JavaScript verwendet, daher habe ich ein paar Schwierigkeiten.

nonce und client_id – Sind das einfach zufällige 16- bzw. 32-Byte-Strings, die hex-kodiert sind?
public_key – Hast du Tipps, wie man diesen generiert? Ich versuche, die hier verfügbare Ressource zu nutzen, was mir einen SecKeyRef gibt. Soll ich diesen in NSData umwandeln und dann UTF-8-kodieren?

Hättest du zufällig Code-Snippets in Swift oder Objective-C? Ich werde das schon hinbekommen, aber da alles für mich neu ist, wäre jede kleine Hilfe sehr willkommen.

Nonce ist ein zufälliger Schlüssel; siehe generateNonce hier: DiscourseMobile/js/site_manager.js at main · discourse/DiscourseMobile · GitHub

client_id ist das deviceToken der App. Es wird der App über GitHub - react-native-push-notification/ios: React Native Push Notification API for iOS. · GitHub übergeben.

public_key wird von GitHub - SamSaffron/react-native-key-pair · GitHub generiert. Diese Bibliothek ist recht klein, und die relevanten Teile sind in Objective-C geschrieben.

Hey Penar, danke für die Links, sehr hilfreich.
Ich mache Fortschritte, bin aber der Meinung, dass ich meinen öffentlichen Schlüssel falsch formatiere. Wie sieht das Format hier aus?

https://myserver.com/user-api-key/new?client_id=11223344556677889900AABBCCDDEEFF11223344556677889900AABBCCDDEEFF&nonce=11223344556677889900AABBCCDDEEFF&application_name=AppName&public_key=-----BEGIN%20PUBLIC%20KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtoNwaYpbUcX1vqxPkxRA%0D1EyfLPxkKL6zgx4Fkk9zkYbTPTWQFuqy+O1EJtVnsW+Tx8iarFLI+ypghcx22nI0%0DN/hDFYsaT/xri+LLDc790uf2UtyolgBJfkyjJDxIXXy0pdpi6f2dgKMN2holDkxf%0DTUUnZad+wE8gT8IciX1XjU97MOngSV+IDeKPLomTuTiI1Z0hJe4WDww5+53ci4o4%0DoE5A79H/Fz/QY8vDLTcBNrQ6OdJYsRqhE5M+1sNmxpqDKT+9NcAPY7yphxm1iLuV%0Dm7c6K/xrbZExGDQd1qHvggT2ldMJIsmQEnleMdfuaYLh8+EYt8LNQ8X86V0Jj+9C%0DmQIDAQAB-----END%20PUBLIC%20KEY-----&auth_redirect=appname://auth&scopes=notifications,session_info,one_time_password

In der Log-Konsole sehe ich:
OpenSSL::PKey::RSAError (Neither PUB key nor PRIV key: nested asn1 error) /var/www/discourse/app/controllers/user_api_keys_controller.rb:189:in `initialize’

Danke.

Ich habe gerade ein Skript veröffentlicht, das genau das tut, @xceph.

Schau dir Erstellen von Benutzer-API-Schlüsseln zum Testen an.

Danke! Ich habe gerade Fortschritte gemacht. Mein Problem lag in der Kodierung der Parameter. Ich habe den iOS-URLQueryAllowedCharacterSet verwendet, der “/” oder “+” nicht kodiert. Sobald ich ein Test-Ruby-Skript erstellt hatte, um die Zeile, bei der ich abstürzte, herauszufiltern, konnte ich rückwärts arbeiten. Danke!

Der Redirect scheint nicht richtig zu funktionieren, wenn ich die ASWebAuthenticationSession wie von Penar vorgeschlagen verwende. Die Aufrufe scheinen wie erwartet zu funktionieren: Ich erhalte das Dialogfeld „Authorize

[quote=“xceph, Beitrag: 14, Thema: 114788”]
Die Aufrufe scheinen wie erwartet zu funktionieren: Ich erhalte das Dialogfeld „Autorisieren

Ja, es lag an der Einstellung „Erlaubte Benutzer-API-Auth-Weiterleitungen

Wenn du den Quellcode unserer App ansiehst, findest du Beispiele, wie die Dekodierung funktioniert. Es war eine ziemlich komplexe Menge an Code, um alles zum Laufen zu bringen.

Danke, ich habe es endlich zum Laufen gebracht. Ich werde später einige Code-Snippets posten, um anderen zu helfen, die dies nativ auf iOS umsetzen möchten. Danke für die Unterstützung.

Kann der auf diese Weise erstellte API-Token verwendet werden, um eine Anmeldung in einer Webview zu authentifizieren? Ich habe angenommen, dass die App das tut, aber ich arbeite noch an diesem Teil. Ich versuche, sowohl API-Zugriff als auch die Möglichkeit, über den normalen Web-Client Reface zu browsen, über eine einzige Anmeldung bereitzustellen.