Saat ini kami memiliki banyak masalah seputar aliran OAuth kami, peralihan akun, manajemen token, merek masing-masing, dll. Ini adalah upaya untuk membuat semua ini lebih dapat ditindaklanjuti di bawah aplikasi account
baru yang akan menangani semua kekhawatiran ini.
Aplikasi yang bertindak sebagai penyedia OAuth dan UI konfigurasi berfitur lengkap dan bermerek seputar semua masalah akun dan autentikasi
Web
Saya pikir masalah besar dengan implementasi saat ini adalah kurangnya kejelasan dan konteks bagi pengguna. Sulit untuk mengenali aplikasi OAuth sebagai entitas autentikasi independen. Alasan adalah:
Saya telah membuat tiga gambar rangka yang memberikan gambaran tentang bagaimana saya membayangkan aplikasi akun:Lihat gambar rangka
(perhatikan pengalih akun terintegrasi di dropdown pengguna di kanan atas)
Ya. @johanstokking @htdvisser , beri tahu saya apakah menurut Anda bagus untuk melanjutkan.
Mengenai seluruh masalah kebingungan masuk/keluar antara konsol dan penyedia oauth, inilah rencana saya:
Account
untuk aplikasi akun (bukan Logo TTS) dan menggunakan komponen header yang sama yang juga kami gunakan untuk konsol (cc @pierreph)/console/login
/account/login
, ketika tidak memiliki token akses (valid)/users/logout
yang akan memicu logout yang dapat dirujuk dari mana sajaJika saya tidak mendengar keluhan tentang rencana ini, saya akan mulai menerapkannya.
Kedengarannya seperti rencana yang bagus. Saya setuju kita tidak perlu keluar secara eksplisit dari Konsol dan tetap masuk melalui OAuth di UX, meskipun itu akan berfungsi seperti itu di bawahnya.
Apa yang Anda perlukan untuk logout lintas-asal? Bukankah ini merupakan pendekatan dua langkah yang sederhana; logout "halaman" untuk menghapus token akses tersimpan Konsol, lalu arahkan kembali ke halaman logout umum tempat aplikasi Akun logout? Atau apakah Anda menginginkan ini tanpa pengalihan tetapi memposting ke titik akhir logout?
Untuk logout, kita bisa mendapatkan inspirasi dari logout OpenID Connect. Ringkasan yang bagus dapat ditemukan di sini: https://medium.com/@robert.broeckelmann/openid -connect-logout-eccc73df758f
Kedengarannya seperti rencana yang bagus. Saya setuju kita tidak perlu keluar secara eksplisit dari Konsol dan tetap masuk melalui OAuth di UX, meskipun itu akan berfungsi seperti itu di bawahnya.
Apa yang Anda perlukan untuk logout lintas-asal? Bukankah ini merupakan pendekatan dua langkah yang sederhana; logout "halaman" untuk menghapus token akses tersimpan Konsol, lalu arahkan kembali ke halaman logout umum tempat aplikasi Akun logout? Atau apakah Anda menginginkan ini tanpa pengalihan tetapi memposting ke titik akhir logout?
Pendekatan dua langkah tidak masalah. Kekhawatiran saya adalah bahwa logout dari aplikasi akun harus dinonaktifkan CSRF, artinya siapa pun yang memiliki tautan logout dapat memikat seseorang untuk keluar dari akun mereka. Ini juga saat ini dimungkinkan dengan tumpukan v2 ( mengklik di sini akan mengeluarkan Anda ).
Saya pikir untuk saat ini ini dapat diterima tetapi bukan praktik terbaik.
Saya telah melakukan beberapa pekerjaan sekarang untuk aplikasi akun baru:
Saya melakukan ini dengan melakukan hardcoding token akses, untuk dapat menggunakan API tumpukan. Saat ini saya tidak dapat melanjutkan dengan implementasi yang tepat, karena saya tidak tahu apa cara terbaik untuk mendapatkan token akses untuk aplikasi akun.
Saat ini, "aplikasi oauth" hanyalah SPA yang terhubung ke titik akhir auth dari server oauth (login, logout, dan titik akhir terkait akun lainnya yang tidak memerlukan token akses).
@htdvisser menyebutkan kepada saya bahwa ide awal kami adalah memiliki aplikasi akun sebagai klien oauth terpisah, menggunakan jenis pemberian kata sandi. Saya pikir kita harus membuka diskusi tentang ini, karena:
Saya sudah mengatakan kepada @htdvisser bahwa seluruh aspek otentikasi/otorisasi yang didelegasikan ini agak berlebihan bagi saya dan saya tidak merasa cukup berpengetahuan untuk bertanggung jawab atas masalah yang sensitif terhadap keamanan.
Apa yang harus kami tuju adalah aliran yang membuat aliran otentikasi klien resmi kami terasa seperti otentikasi asli (lihat juga komentar saya yang lain ), yang berarti bahwa login dan logout bersifat global dan tidak boleh ada perbedaan antara status terotentikasi klien dan penyedia otorisasi.
Jadi, saya membutuhkan bantuan dan masukan untuk melanjutkan dengan aplikasi akun. Bagaimana kita bisa mengkoordinasikan ini?
tergantung pada sumbernya, jenis pemberian kata sandi tidak disarankan, bahkan untuk klien "resmi" dan tepercaya
Ya, pemberian kata sandi tidak boleh digunakan, lihat spesifikasi dan alasannya di sini: https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13#section -3.4
Saat ini diblokir oleh #2148
Jadi setelah terlibat dengan ini untuk sementara waktu sekarang, saya pikir saya perlu beberapa masukan.
Ide asli dari aplikasi akun adalah untuk menggantikan aplikasi oauth saat ini dan memperluas fungsionalitas ke manajemen profil dan sesi (lihat OP). Masalah dengan ini adalah bahwa untuk mengimplementasikan fungsionalitas seperti itu, aplikasi akan memerlukan token akses, yang pada dasarnya berarti bahwa aplikasi akun akan menjadi penyedia dan klien OAuth.
Ide saya adalah untuk memperkenalkan klien OAuth baru ( account
) dan dari sisi frontend, untuk memadukan fungsionalitas dengan aplikasi OAuth saat ini. Bagi pengguna, akan tampak seolah-olah penyedia OAuth (masuk, mendaftar, memvalidasi akun, dll) dan klien aplikasi akun (pengaturan profil, manajemen sesi, manajemen otorisasi) adalah satu dan aplikasi yang sama, sementara di latar belakang, ada adalah pemisahan teknis antara penyedia OAuth dan klien. Di backend, klien akun akan menjadi bagian dari paket oauth
. Dari segi frontend, kami juga dapat memperlakukan kedua hal tersebut sebagai aplikasi yang sama, menggunakan titik masuk yang sama ( account.js
).
Demikian juga, perutean akan mencerminkan pencampuran ini, misalnya:
/account/login
untuk login oauth [lapisan penyedia OAuth]/account/register
untuk pendaftaran pengguna [lapisan penyedia OAuth]/account/forgot-password
untuk pendaftaran pengguna [lapisan penyedia OAuth]/account/client/login/ttn-stack
untuk login klien (otorisasi) [Lapisan klien OAuth]/account/client/oauth/callback
untuk menukar kode auth [lapisan klien OAuth]/account
halaman ikhtisar klien oauth [lapisan klien OAuth]Atau, kita dapat memisahkan kedua masalah tersebut, membiarkan penyedia OAuth ( /oauth
via pkg/oauth
) apa adanya dan memperlakukan aplikasi akun ( /account
melalui pkg/account
) sebagai hal yang benar-benar terpisah, seperti yang kita lakukan dengan konsol. Penyedia OAuth kemudian hanya akan bertanggung jawab atas masalah autentikasi, termasuk otorisasi dan pendaftaran akun pengguna, tetapi tidak akan memiliki tampilan terotentikasi sendiri seperti saat ini. Sebagai gantinya, setelah login, itu akan mengarahkan ulang ke aplikasi akun secara default, yang kemudian akan mengambil token secara otomatis.
Saya merasa bahwa solusi pertama mungkin menghindari beberapa kebingungan yang saat ini kami miliki seputar otentikasi dan manajemen akun, tetapi saya tidak dapat memperkirakan apakah itu akan menimbulkan komplikasi lain. Solusi kedua tampaknya lebih bersih, tetapi pertanyaannya adalah bagaimana mengomunikasikan/mencap pemisahan tersebut. Misalnya, apakah keduanya masih harus dikomunikasikan sebagai "Aplikasi akun"? Atau haruskah The Things Stack Single Sign On
dan The Things Stack Account Application
?
Tolong beri tahu saya pendapat Anda.
Hmm, mundur selangkah, apa tujuan menjadikan aplikasi akun sebagai klien OAuth? Apa fungsi melalui OAuth yang kita inginkan di sana?
Semua itu memerlukan token akses karena itulah satu-satunya cara untuk mengotorisasi RPC masing-masing.
Kami membutuhkan pemisahan penyedia OAuth -- yang bisa bersifat eksternal, misalnya "Komunitas Jaringan Hal" -- dan Manajemen pengguna -- yaitu tentang mengelola bidang entitas Pengguna yang disimpan dengan The Things Stack, termasuk poin @kschiffer tulis di komentar di atas.
Titik akhir /api/v3/*
tidak menerima autentikasi cookie, karena mereka mendukung CORS. Mereka hanya bekerja dengan kunci API dan Token Akses.
- Pengaturan profil (nama, email, gambar profil)
- Manajemen sesi (tinjau, cabut)
- Manajemen otorisasi (meninjau, mencabut)
- (Berpotensi pengaturan meta terkait TTES lainnya di masa mendatang)
Semua itu memerlukan token akses karena itulah satu-satunya cara untuk mengotorisasi RPC masing-masing.
Kami juga dapat membuat bagian ini dari konsol tetapi itu berarti bahwa konsol akan mencampuradukkan kekhawatiran sampai batas tertentu. Saya dapat melihat situasi di mana akan lebih baik untuk melakukan manajemen akun tanpa overhead dari semua fungsi konsol lainnya, tetapi mungkin saya merekayasa ini secara berlebihan ️.
Umumnya, pertanyaannya adalah apakah kita ingin melihat konsol hanya sebagai alat untuk mengelola hal-hal yang terkait dengan jaringan. Kami dapat membukanya untuk menjadi platform manajemen tujuan umum untuk semua hal terkait TTS atau kami dapat lebih atomik dan tetap berpegang pada pemisahan dan menggunakan aplikasi/klien yang berbeda untuk masalah yang berbeda. Ini pertanyaan strategis. Saya melihat kasus untuk keduanya.
Saya tidak berpikir konsol (semua konsol, karena ada konsol di setiap cluster) harus memiliki hak penuh atas pengguna. Konsol tidak boleh digunakan untuk mengelola klien OAuth resmi, sesi, alamat email utama, info kontak. Memiliki aplikasi manajemen Pengguna khusus (aplikasi akun) jauh lebih baik.
Memang, poin yang bagus. Kemudian kembali ke pertanyaan awal .
Pendapat saya adalah:
Pendekatan campuran:
Pendekatan terpisah:
Saya condong ke arah pendekatan campuran.
- Pengaturan profil (nama, email, gambar profil)
- Manajemen sesi (tinjau, cabut)
- Manajemen otorisasi (meninjau, mencabut)
- (Berpotensi pengaturan meta terkait TTES lainnya di masa mendatang)
Ini adalah aplikasi akun, kan? Bukan OAuth?
- Memperkenalkan aplikasi baru di sebelah aplikasi oauth, yang membutuhkan branding dan komunikasi yang masuk akal
Untuk apa aplikasi OAuth itu?
Bisakah Anda membuat daftar fitur untuk pengguna dari apa yang ditambahkan klien OAuth ke aplikasi akun, yang tidak dapat kami buat di aplikasi akun, kemungkinan melalui titik akhir baru?
Ini adalah aplikasi akun, kan? Bukan OAuth?
Ya, ini adalah aplikasi akun. Tetapi rencananya adalah apa yang kami miliki saat ini sebagai aplikasi OAuth menjadi bagian dari aplikasi akun.
Untuk apa aplikasi OAuth itu?
Untuk autentikasi (sebagai bagian dari alur OAuth), pendaftaran pengguna, otorisasi klien, penyetelan ulang sandi. Pada dasarnya segala sesuatu yang berkaitan dengan otentikasi pengguna dan otorisasi klien.
Bisakah Anda membuat daftar fitur untuk pengguna dari apa yang ditambahkan klien OAuth ke aplikasi akun, yang tidak dapat kami buat di aplikasi akun, kemungkinan melalui titik akhir baru?
Masalahnya lebih pada sebaliknya, kami tidak bisa begitu saja memperluas aplikasi OAuth kami saat ini dengan fungsionalitas yang kami inginkan untuk aplikasi akun, karena kami perlu mendapatkan token akses. Ini sedikit masalah ayam dan telur. Jika ada cara otorisasi yang berbeda untuk fungsionalitas aplikasi akun (sesi, otorisasi, dll), misalnya melalui cookie sesi yang dimiliki aplikasi OAuth, maka itu akan berbeda. Tapi dari apa yang saya lihat ini tidak layak.
Apakah aplikasi OAuth merupakan aplikasi yang berdiri sendiri? Apakah ini menerapkan alur pengalihan untuk klien OAuth? Atau apakah itu klien OAuth itu sendiri?
Penekanan saya:
Ide saya adalah untuk memperkenalkan klien OAuth baru (
account
) dan dari sisi frontend, untuk memadukan fungsionalitas dengan aplikasi OAuth saat ini . Bagi pengguna, akan tampak seolah-olah penyedia OAuth (masuk, mendaftar, memvalidasi akun, dll) dan klien aplikasi akun (pengaturan profil, manajemen sesi, manajemen otorisasi) adalah satu dan aplikasi yang sama, sementara di latar belakang, ada adalah pemisahan teknis antara penyedia OAuth dan klien . Di backend , klien akun akan menjadi bagian dari paketoauth
.
saya lihat di sini;
oauth
Saya mencoba memahami proposal, tetapi saya tidak sepenuhnya mengerti apa yang masih ada.
Lalu apa saja fitur yang kita inginkan?
Saya kira 1-6 dapat diimplementasikan tanpa menyentuh OAuth sama sekali, jika kita menggunakan otentikasi sesi. Itu mungkin, kan?
Ya maaf. Kami memiliki sejumlah istilah yang tidak tetap di sini yang membuatnya cukup sulit untuk dijelaskan. Setidaknya itu memberikan wawasan yang baik tentang kompleksitas masalah .
Jadi mari kita ambil status quo:
penyedia OAuth
Entitas yang memberikan otorisasi (dan dalam kasus kami juga autentikasi) menurut spesifikasi OAuth 2.0. Dalam kasus kami, itulah paket pkg/oauth
, yang pada gilirannya menggunakan aplikasi OAuth (lihat di bawah) untuk mengimplementasikan antarmuka pengguna yang diperlukan untuk mendapatkan informasi pengguna (render login, registrasi, tampilan otorisasi, dll.).
aplikasi OAuth
Ini adalah aplikasi web reaksi di frontend. Kode frontend kami terdiri dari aplikasi yang berbeda (dengan titik masuk yang berbeda oauth.js
/ console.js
) yang berbagi bagian umum seperti komponen reaksi dan utilitas
klien OAuth
Klien terdaftar yang menggunakan OAuth untuk autentikasi dan otorisasi, seperti konsol atau CLI.
paket sumpah
Paket Go yang bertanggung jawab untuk mengimplementasikan penyedia OAuth. Itu pkg/oauth
.
Jadi Anda lihat, ada tiga atau empat lapisan berbeda yang berperan di sini. Masalahnya adalah jika kita mempertahankan cara kita melakukan otorisasi saat ini, kita perlu memiliki sesuatu yang memainkan semua peran yang diuraikan di atas pada saat yang bersamaan.
Saya kira 1-6 dapat diimplementasikan tanpa menyentuh OAuth sama sekali, jika kita menggunakan otentikasi sesi. Itu mungkin, kan?
Ya. 1-4 sudah dimungkinkan tanpa token oauth/akses. 5 dan 6 saat ini membutuhkan token akses. 7. ii belum dilaksanakan. Jika 5 dan 6 dimungkinkan tanpa token akses maka kami memang tidak memerlukan klien oauth lain untuk melakukan ini. Kami masih perlu mempertimbangkan bahwa setiap fungsi yang mungkin ingin kami tambahkan ke aplikasi akun di masa mendatang tidak boleh menggunakan token akses sebagai satu-satunya sarana otorisasi.
Jika 5 dan 6 dimungkinkan tanpa token akses maka kami memang tidak memerlukan klien oauth lain untuk melakukan ini. Kami masih perlu mempertimbangkan bahwa setiap fungsi yang mungkin ingin kami tambahkan ke aplikasi akun di masa mendatang tidak boleh menggunakan token akses sebagai satu-satunya sarana otorisasi.
Benar. Ini sangat masuk akal bagi saya. Ini juga merupakan dasar yang lebih baik untuk "mode sudo", di mana pengguna dapat melakukan hal-hal _only_ di aplikasi akun, misalnya setelah memasukkan kembali kata sandi Anda. Jadi ya, mungkin ada beberapa tumpang tindih antara apa yang dapat dilakukan klien OAuth dan aplikasi akun, tetapi tumpang tindih itu tampaknya tidak besar bagi saya. Saya melihat nilai dalam menjaga hal-hal yang didedikasikan untuk aplikasi akun.
Baiklah, kedengarannya bagus.
@htdvisser Apakah Anda memiliki keberatan? Dan jika tidak, dapatkah Anda mengarahkan saya ke file/paket relatif untuk otorisasi, karena saya kira Anda tidak akan punya waktu untuk mengerjakan ini dalam waktu dekat (?).
Seperti yang saya komentari sebelumnya, titik akhir /api/v3/*
tidak menerima auth cookie, karena mereka mendukung CORS. Jika Anda ingin mulai menerima cookie auth, Anda perlu melihat baik-baik header CORS kami, karena kami benar-benar tidak ingin penyerang membuat permintaan lintas-asal yang diautentikasi cookie ke titik akhir ini.
Semua API kami adalah gRPC, dan autentikasi dilakukan dengan header Authorization
, yang disebarkan ke gRPC sebagai metadata permintaan. Implementasi autentikasi sesi dapat terlihat seperti ini:
SessionToken
ke pkg/auth/auth.go
Session
, mirip dengan yang kita lakukan dengan kunci API dan Token Akses.Authorization
sebagai SessionTokenSessionToken
sebagai case
ke switch tokenType {
di pkg/identityserver/entity_access.go
Satu hal yang perlu dipertimbangkan di sini adalah ini juga berarti bahwa aplikasi akun dan API v3 harus dilayani dari asal yang sama. Jika tidak, autentikasi cookie tidak akan berfungsi karena konteks autentikasi terdiri dari asal yang berbeda.
Tidak yakin seberapa dapat diterima itu. Setidaknya dalam praktiknya, kami tampaknya menggunakan asal yang sama dalam penerapan kami.
Ya, mereka akan berada di asal yang sama.
@kschiffer beri tahu kami bagaimana kami dapat membuka blokir kemajuan di sini.
Saya menulis ringkasan di sini: https://github.com/TheThingsNetwork/lorawan-stack/pull/2850#issuecomment -657497193
Oke, mari kita lanjutkan percakapan itu di sini.
@kschiffer Setelah mengerjakan ini sebentar:
- Bagian depan aplikasi oauth pada dasarnya hanya terdiri dari layar otorisasi
Ya
- Saya pikir sangat menjengkelkan harus mempertahankan konfigurasi
is.oauth.ui.*
hanya untuk itu
[...]- Saya juga sedikit tidak yakin tentang batasan yang tepat tentang bagaimana kami dapat mengubah konfigurasi tumpukan tanpa merusak CC
- Saya sedikit kurang beruntung dengan menemukan solusi yang layak di sini dan sangat membutuhkan masukan
Kami tidak dapat merusak konfigurasi di V3, tetapi kami dapat memperkenalkan konfigurasi baru, menghentikan konfigurasi lama, menggunakan konfigurasi lama sebagai fallback, dan mengajukan masalah TODO berlabel bump/major
untuk menghapus konfigurasi lama.
Jadi saran saya adalah memperkenalkan konfigurasi baru yang akan menjadi pengganti lengkap dan mengaktifkan aplikasi akun baru. Untuk kompatibilitas mundur, ini akan berfungsi tanpa pengguna menentukan konfigurasi baru ini, yaitu mengandalkan nilai default yang waras dan konfigurasi lama melalui is.oauth.ui.*
.
@kschiffer apa statusnya di sini?
Saat ini rebasing pekerjaan saya di perancah baru, yang sedang berlangsung di sini: #3453
Selanjutnya adalah rebasing, fixing dan PRing tampilan yang diautentikasi dan menyesuaikan desain saat ini dengan branding baru.
@kschiffer apa statusnya di sini?
Aplikasi Akun telah diperkenalkan di 3.11. Saat ini masih hilang adalah:
OKE. https://github.com/TheThingsNetwork/lorawan-stack/issues/488 sepertinya sudah ditutup.
Ini telah menjadi masalah besar. Bisakah Anda mengajukan satu atau dua masalah baru untuk yang di atas untuk menggantikan yang ini, sehingga dapat ditutup?