Bagaimana cara melakukan otentikasi stateless (tanpa sesi) & tanpa cookie?

107

Bob menggunakan aplikasi web untuk mencapai sesuatu. Dan:

  • Browsernya sedang diet, oleh karena itu tidak mendukung cookie .
  • Aplikasi web adalah salah satu yang populer, ia berurusan dengan banyak pengguna pada saat tertentu - ia harus berskala baik. Selama sesi penyimpanan akan membatasi jumlah koneksi simultan , dan, tentu saja, akan membawa penalti kinerja yang tidak dapat diabaikan , kami mungkin ingin memiliki sistem tanpa sesi :)

Beberapa catatan penting:

  • kami memiliki keamanan transportasi ( HTTPS dan sahabatnya);
  • di balik tirai, aplikasi web mendelegasikan banyak operasi ke layanan eksternal , atas nama pengguna saat ini (sistem tersebut mengenali Bob sebagai salah satu penggunanya) - ini berarti bahwa kami harus meneruskan kredensial Bob kepada mereka .

Sekarang, bagaimana kita mengotentikasi Bob (pada setiap permintaan)? Cara manakah yang masuk akal untuk menerapkan hal seperti itu?

  • bermain tenis dengan kredensial melalui bidang tersembunyi HTML ... bola berisi kredensial ( nama pengguna & kata sandi ) dan dua raket masing-masing adalah browser dan aplikasi web. Dengan kata lain, kami dapat mengangkut data bolak-balik melalui bidang formulir, bukan melalui cookie. Di setiap permintaan web, browser memposting kredensial. Padahal, dalam kasus aplikasi satu halaman , ini mungkin terlihat seperti bermain squash di dinding karet, daripada bermain tenis , karena formulir web yang berisi kredensial mungkin tetap hidup sepanjang masa halaman web. (dan server akan dikonfigurasi untuk tidak menawarkan kredensial kembali).
  • menyimpan username & password dalam konteks halaman - variabel JavaScript dll. Halaman tunggal diperlukan di sini, IMHO.
  • otentikasi berbasis token terenkripsi. Dalam kasus ini, tindakan log-in akan menghasilkan token keamanan terenkripsi (nama pengguna + kata sandi + sesuatu yang lain). Token ini akan disajikan kembali ke klien dan permintaan yang akan datang akan disertai dengan token. Apakah ini masuk akal? Kami sudah memiliki HTTPS ...
  • lainnya ...
  • upaya terakhir: jangan lakukan ini, simpan kredensial dalam sesi! Sesi itu bagus. Dengan atau tanpa cookie.

Apakah ada masalah web / keamanan yang muncul di benak Anda, berkenaan dengan salah satu ide yang dijelaskan sebelumnya? Sebagai contoh,

  • time-outing - kami dapat menyimpan stempel waktu , bersama dengan kredensial (stempel waktu = waktu Bob memasukkan kredensial-nya). Misalnya saat SEKARANG - stempel waktu> ambang batas , kami mungkin menolak permintaan tersebut.
  • Perlindungan skrip lintas situs - tidak boleh berbeda dengan cara apa pun, bukan?

Terima kasih banyak telah meluangkan waktu untuk membaca ini :)

turdus-merula
sumber
1
Anda bisa menambahkan token ke setiap URL. ASP.NET memiliki mode (warisan) untuk melakukan itu. Ini membuktikan bahwa itu bisa berhasil.
usr
1
Dimana semuanya? :)
turdus-merula
2
Saya pikir Anda sudah memiliki ide yang cukup bagus tentang opsi yang tersedia. Percayai alasan Anda dan putuskan sendiri.
usr
apakah plugin seperti silverlight of flash merupakan pilihan?
Giu
@usr tidak yakin apakah itu ide yang baik seolah-olah peretas yang mengakses log websever Anda dapat mencuri token Anda dan masuk ke sistem Anda.
GibboK

Jawaban:

74

Ah, saya suka pertanyaan ini - mempertahankan sesi tanpa sesi.

Saya telah melihat banyak cara untuk melakukan ini selama tugas saya selama penilaian aplikasi. Salah satu cara yang populer adalah cara bermain tenis yang Anda sebutkan - mengirimkan nama pengguna dan kata sandi di setiap permintaan untuk mengotentikasi pengguna. Ini, menurut saya, tidak aman, terutama jika aplikasinya tidak satu halaman. Ini juga tidak dapat diskalakan, terutama jika Anda ingin menambahkan otorisasi ke aplikasi Anda selain otentikasi di masa mendatang (meskipun saya rasa Anda juga dapat membuat sesuatu berdasarkan login)

Salah satu mekanisme yang populer, meskipun tidak sepenuhnya tanpa kewarganegaraan (dengan asumsi Anda menjalankan JavaScript) adalah menyematkan cookie sesi di JavaScript. Petugas keamanan dalam diri saya berteriak tentang ini, tetapi ini benar-benar bisa berfungsi - setiap permintaan memiliki fileX-Authentication-Tokenheader atau semacamnya, dan Anda memetakannya ke database, penyimpanan file dalam memori, dll. di backend untuk memvalidasi pengguna. Token ini dapat memiliki waktu tunggu kapan pun Anda tentukan, dan jika waktunya habis, pengguna harus masuk lagi. Ini cukup skalabel - jika Anda menyimpannya dalam database, satu pernyataan SQL-nya dieksekusi, dan dengan indeks yang benar, hanya perlu sedikit waktu untuk mengeksekusinya, bahkan dengan beberapa pengguna secara bersamaan. Pengujian beban di sini pasti akan membantu. Jika saya membaca pertanyaan dengan benar, ini akan menjadi mekanisme token terenkripsi Anda - meskipun, saya sangat menyarankan agar Anda menggunakan token acak secara kriptografis, katakanlah 32 karakter, dibandingkan menggunakan kombinasi nama pengguna + kata sandi + apa pun - dengan cara ini, tetap ada tidak dapat diprediksi, tetapi Anda masih dapat mengaitkannya dengan ID pengguna atau semacamnya.

Apa pun yang akhirnya Anda gunakan, pastikan itu dikirimkan kepada Anda dengan aman. HTTPS melindungi Anda di seluruh jaringan, tetapi tidak melindungi Anda jika Anda membocorkan token sesi melalui URL (atau lebih buruk, kredensial melalui URL). Saya akan merekomendasikan menggunakan tajuk, atau jika itu tidak memungkinkan, mengirim token melalui permintaan POST setiap saat (ini berarti bidang formulir tersembunyi di browser pengguna.) Pendekatan terakhir dalam menggunakan permintaan POST harus menggunakan pertahanan CSRF, cukup dalam kasus, meskipun saya curiga menggunakan token itu sendiri mungkin semacam pertahanan CSRF.

Terakhir, namun tidak kalah pentingnya, pastikan Anda memiliki beberapa mekanisme di backend untuk membersihkan token yang kedaluwarsa. Ini telah menjadi kutukan bagi banyak aplikasi di masa lalu - database token otentikasi yang berkembang pesat yang sepertinya tidak pernah hilang. Jika Anda perlu mendukung banyak login pengguna, pastikan Anda membatasi jumlahnya, atau memiliki batas waktu yang lebih singkat pada setiap token. Seperti yang saya katakan sebelumnya, pengujian beban mungkin menjadi jawaban untuk ini.

Ada beberapa masalah keamanan lain yang dapat saya pikirkan, tetapi terlalu luas untuk ditangani pada tahap ini - jika Anda mengingat semua kasus penggunaan (dan penyalahgunaan), Anda mungkin dapat melakukan implementasi yang cukup baik dari sistem ini.

Karthik Rangarajan
sumber
Tidak bisakah Anda melakukan apa yang dilakukan kerangka kerja bermain dan mengirim cookie yang ditandatangani kepada pengguna? Lalu apakah cookie itu dikirim kembali ke server untuk setiap permintaan berikutnya?
j akan
8
> Browsernya sedang diet, oleh karena itu tidak mendukung cookie.
Karthik Rangarajan
4
Apakah salah satu dari saran ini benar - benar tanpa kewarganegaraan / tanpa sesi ? Dari lima paragraf utama Anda (mulai dari posting edisi 2013-12-19): # 1 adalah pengantar, # 2 mengusulkan sesi ekstra-kludgy Web2.0 ™ -Favored, # 3 hanyalah peringatan, # 4 membahas implikasinya kewarganegaraan , dan # 5 adalah protes yang samar-samar ... bagaimana ini bisa diterima ?? Paling-paling ini sangat informatif!
JamesTheAwesomeDude
1

Tentang opsi log-in - Saya pikir biasanya Anda juga ingin mendukung sesi untuk tamu.

Jadi, jika Anda ingin memaksakan login, opsi token terenkripsi mungkin bagus. Mungkin bagus juga untuk sesi tamu. Di arah lain, saya akan menggabungkan antara menambahkan token ke URL dan opsi tenis.

Perhatikan bahwa mengirim kredensial hanya di URL mungkin berbahaya. Misalnya, Anda mungkin membocorkan token melalui header referer HTTP atau bahkan oleh seseorang yang baru saja memeriksa lalu lintas atau mengawasi komputer Anda.

Hal lain, bahkan jika Anda dapat menggunakan cookie, saya akan merekomendasikan Anda untuk menambahkan token acak atau verifer acak, untuk melindungi diri Anda dari serangan Cross Site Request Forgery (CSRF).

Gari BN
sumber
3
Sesi adalah status yang disimpan di server. Pertanyaannya menanyakan otentikasi tanpa kewarganegaraan.
Kwebble