REST API istifadə edərək kimlik doğrulaması necə edilir? (Browser + Yerli müştərilər)

Rails istifadə edərək bir web proqram yaratmaq. Hal-hazırda Devise'i HTTP seansları ilə istifadə edirəm ki, bu qurmaq və işləmək üçün kifayət qədər asan idi.

Ərizə bir AJAX veb tətbiqi təmin edən bir URLdən ibarətdir. Qalan mövcud URL'ler REST API'sına aiddir. Beləliklə, hər bir kiçik məlumat sorğusu AJAX vasitəsilə həyata keçirilir.

İndi yerli müştərilərə dəstək olmaq üçün hər şeyi genişləndirmək istərdim. Mən hesabsız autache, http əsas və digest auth, http sessiyaları, cookies, xsrf və s. Haqqında çox oxudum İndi hiss edirəm ki, mənim təhlükəsiz bir tətbiqim yoxdur, çünki onun bir hissəsini ələ keçirmək üçün hər zaman bir yol var.

1: HTTP Session Vs. dövlət olmadan autentifikasiya simvolu

Fərq nədir? Mən başa düşmürəm.

  • HTTP seansı:

    • Müştəri URL tələb edir (server üçün ilk tələb)
    • Server adi cavabı unikal bir simli (== iclas ID) verir.
    • Müştəri bu xəttləri hər bir müraciətlə göndərməlidir (HTTP başlığı ilə avtomatik olaraq həyata keçirilir)
    • Müştərinin qeydləri → Server bu sessiya şəxsiyyətinin qeydiyyatdan keçdiyini xatırlayır
    • Müştəri auth → tələb edən bir səhifəyə baxır, xüsusi bir şey yoxdur, çünki oturum ID avtomatik olaraq HTTP başlığı vasitəsilə serverə göndəriləcək
  • autent token:

    • Müştəri sorğusunun URL (serverə ilk sorğu)
    • Server sadəcə hər hansı bir əsas və ya simge və ya id olmadan adi cavab verir
    • (burada xüsusi bir şey yoxdur)
    • Müştərinin qeydləri → Server bir identifikasiyası simvolu yaradır və cavabda müştəri üçün bu token göndərir
    • Müştəri identifikasiyası tələb olunan səhifəni ziyarət edir → Müştəri bir identifikasiya token göndərməlidir

Mənim üçün hər iki yol çox oxşar görünür. Rails ilə, mən də veritabanının içərisində sessiyanı seçə bilərəm ... Devise authen auth token ilə eyni şeyi edər.

2: Doğrulama metodu

İndi POST /users/sign_in edərək {"user":{"email":"e@mail.com","password":"p455w0rd"}} .

Ancaq HTTP əsas auth və HTTP digest auth kimi digər xüsusiyyətlər var, həm də oAuth (mənim məqsədim üçün çox böyük) kimi həllər.

Mən oxuduqlarımdan:

  • Təhlükəsizlik sign_in ilə əlaqədar mövcud POST /users/sign_in və əsas HTTP protokolu arasında fərq yoxdur. Hər ikisi düz mətni istifadə edir.
  • Sign_out üçün əsas HTTP yetkisinin olmaması: Çıxışın brauzer pəncərəsini bağlayan zaman mümkündür.
  • HTTP digest auth böyük bir üstünlüyə malikdir: heç bir parol ötürmür (yalnız parol hash plus təsadüfi yaradılan bir simli)
  • (Alman dili) Vikipediya deyir: HTTP auth digesti bütün brauzerlər tərəfindən dəstəklənmir. Bəlkə bu məlumat köhnə mi?

Nə lazım?

  • verilənlər bazasında saxlanılan istifadəçi adı və şifrə (bcrypt).
  • istifadəçi parolunu dəyişə və parol açıq mətndə göndərilməyəcək. (Sign_up istifadəçisinə gəldikdə eyni problem yaranır). Mümkün çözümlər?
    • Əlbəttə: SSL / TLS istifadə edin
    • müştəri istəməsi want_to_change_password_salt və müştərinin tərəfindəki parolu şifrələmək üçün istifadə edir. , ancaq (!!), mən simli şifrənin üzərindəki simli parolun üstün hissəsini göndərdim. Mənim üçün qeyri-müəyyəndirmi?

3: CSRF token

Artıq qeyd edildiyi kimi, indi REST API istifadə edərək müntəzəm olaraq AJAX saytım var. XSRF-nin qorunması var: veb-sayt relslər tərəfindən çatdırılır və beləliklə, XSRF tokenini yerləşdirir. Mən bunu AJAX istifadə edərək oxudum və POST yerinə yetirdikdən keçirdim. Sonra Rails istənilən məlumatı və sonrakı POST üçün istifadə etdiyim yeni XSRF möcüzəsini qaytarır.

İndi mənim server tətbiqini yerli müştərilərlə işləmək üçün dəyişdirmək istəyirəm. Öz müştəri HTML səhifəsini yükləməyəcək və bu səbəbdən CSRF simgesini qəbul etməyəcəkdir. Buna görə mənə aşağıdakılar baş verdi:

  • XSRF REST məkanı qaynağı yaradın. Buna görə (yerli) müştəri ilk POST edə bilməmişdən əvvəl XSRF tokenini bu resursdan tələb etməlidir.
  • Tam XSRF qorunmasını aradan qaldırın.

Suallar:

  • XSRF-nin qorunması (Rails-də) necə işləyir? Server hansı məlumata müştəriyə məxsus olduğunu necə bilir? Düşündüyüm yeganə yol sessiyalardır. Bu fərziyyə aşağıdakılara gətirib çıxarır:
  • Tam bir muxtar REST API yaratmaq üçün bir seansdan ayırsanız, XSRF qorunması artıq işləməyəcəkdir. Sağ olsun?

4: Kimlik yoxlama olmadan token

Burada əsasən bir çox sualım var:

  • HTTP seansları ilə eyni təhlükəsizlik məsələləri varmı? Yəni demək olar ki, bir sessiya idinin oğurlanması identifikasiya möcüzəsini oğurlamaqla eyni təsir göstərir. Sağ olsun?
  • Auth tokenin sona çatması HTTP seansları ilə eyni şəkildə işləməlidir: server bir zaman damgasını bir yerə (verilənlər bazası sırasıyla sessiya) saxlamalıdır və bunu yoxlamaq lazımdır.
  • Sign_out işi də varmı?
    • Sessiya: Bir sessiyanı serverdə məhv et
    • Kimlik doğrulama simgesi: sunucunun işaretini yok edin
  • Mən oxuduğumdan, server protokollarında GET parametrləri ola bilər və bu səbəbdən token ehtiva edə biləcəyi üçün HTTP başlıqlı (identifikasiya nömrəsi kimi) identifikasiya tokenini saxlamaq daha təhlükəsiz olmalıdır.
  • Sadə kimlik doğrulama simgesi ola bilərmi və ya müştəri öz istifadəçi_idini və ya hətta bir paroldan istifadə etməsi halında daha yaxşı olarsa? BURADA oxudum ki, müştəri göndərməlidir:
    • user_id
    • expiration_date
    • hash (və ya HMAC nədir?) [ user_id , SECRET_KEY , SECRET_KEY ]. SECRET_KEY əsasən server tərəfindən yaradılan təsadüfi bir simli olduğu yerdə.

Yazı üçün üzr istəyirik, amma təhlükəsizlik vacibdir! Və yəqin ki, şəxsi məlumatları verə biləcək dizayn səhvləri etmək istəmirəm.

Təşəkkür edirik :)


Burada bəzi yeni məlumatlar və yeni suallar ;-) :

5: yerli müştərilər

Yerli müştərilərə gəldikdə, sessiyalardan istifadə etmək üçün heç bir sadə yol yoxdur:

  • Brauzer olmadan yerli müştəri

  • Beləliklə, çerezləri idarə etmək asan olmayacaq (və cookies olmadan adi seans idarə edilmir)

Belə ki, 3 variant var:

  • Öz müştərilər üçün seans emalını həyata keçirir. Bu kimi görünür:

    • Daxil ol
    • cookie faylları almaq üçün HTTP cavab başlığını oxuyun
    • Lazım olan bütün çerez məlumatlarını (xüsusən də sessiya materialı olan) yerli olaraq saxlaya bilərsiniz.
    • hər bir sorğu ilə bu sessiya id göndərin.
  • Sessiyalardan istifadə etməyin. Bir müştəri baxımından bu, demək olar ki, 1 ilə eynidır:

    • Daxil ol
    • HTTP başlığından və ya cavab orqanından müəyyən bir identifikasiya tokenini əldə edin (bu sizin tətbiqinizdən asılı olsa da bu sizin tətbiqinizdir)
    • Bu möcüzəni yerli olaraq saxlayın
    • Hər mə'lumatla bu möcüzə göndərin
  • Hibrid yanaşma Bu, əsasən, server bir brauzer və öz müştərisi arasında fərqlənməli və təmin edilmiş sessiya və sessiya məlumatlarını yoxlamaq və ya (öz müştəriləri üçün) verilmiş identifikasiya məlumatını doğruldur.

6: CSRF, vətəndaşlığı olmayan (= sessiya yox / çerez yoxdur) auth

CSRF Protection, istifadəçilərinizi qeydiyyatdan keçmiş istifadəçinizin adına API-lərinizin hər hansı bir istəkini yerinə yetirməyə çalışdıqları zərərli saytlardan qoruyur, ancaq istifadəçi barədə məlumatınız olmadan. Sessiyalardan istifadə edərkən bu çox sadədir:

  • İstifadəçi API-ya qeydə alınır
  • Sessiya yaradılıb
  • Bu sessiya identifikasiyası olan bir cookie, istifadəçi brauzerinizdə təyin olunacaq.
  • Istifadəçinizin etdiyinə dair hər bir tələb, sizin API-yə avtomatik olaraq təsdiqlənir, çünki brauzer API-nin hər bir tələbi ilə birlikdə bütün çerezləri (seqment identifikasiyası daxil olmaqla) göndərəcəkdir.

Beləliklə, hücum edən sayt sadəcə aşağıdakıları etməlidir:

  • API'ınıza işarə edən xüsusi HTML <form> yazın
  • Istifadəçi bir şəkildə Yaddaş düyməsini basın

Əlbəttə, bu forma belə bir şeyə bənzəyir:

 <form action="http://your.api.com/transferMoney" method="post"> <input type="hidden" name="receiver" value="ownerOfTheEvilSite" /> <input type="hidden" name="amount" value="1000.00" /> <input type="submit" value="WIN MONEY!!" /> </form> 

Bu, aşağıdakı fərziyyələrə gətirib çıxarır:

  • CSRF qorunması yalnız zəruri deyil, çünki brauzerlər avtomatik olaraq çerez göndərirlər.

  • Yerli müştərilərə CSRF qorunmasına ehtiyac yoxdur (əlbəttə ki, brauzeriniz yerli tətbiqinizin identifikasiya məlumatlarına (token, cookie və s.) Daxil ola bilmir və yerli ərizə brauzerdən API ilə ünsiyyət qurmaq üçün istifadə etməyəcəkdir)

  • İstifadəçinin kimliyini təsdiq etmək üçün çerezlərdən istifadə etməyən bir API dizaynınız varsa, CSRF etmək üçün heç bir yol yoxdur. Təcavüzkarın şəxsiyyət vəsiqəsinin məlumata sahib olduğunu bilmək və açıq bir şəkildə zərərli bir istək göndərmək lazımdır.

Ərizənizi ləğv etmək istəyirsinizsə, əlbəttə ki, CSRF-i qeyri-dövlət identifikasiyası mexanizmi ilə birlikdə istifadə edə bilərsiniz, amma əminəm ki, əlavə təhlükəsizlik təkmilləşdirilməsi yoxdur.


7: Seçim üçün düzgün HTTP üsulları

In / Out və Out / Out:

GET (heç olmasa) üç səbəbdən istifadə etməyin :

  • CSRF qorunması əksər hallarda yalnız POST, PUT, PATCH və DELETE qoruyur və bu səbəbdən CSRF, GET tələbini istifadə edərkən məlumat olmadan sistemə gələ bilər.

  • GET tələbləri tətbiqin vəziyyətini heç vaxt dəyişdirməməlidir. Sessiyalardan istifadə edərkən, giriş / çıxış etdiyiniz zaman proqramın vəziyyəti dəyişir, çünki sessiya yaradılır və ya məhv edilir.

  • GET tələbindən istifadə edərkən və URL parametrləri (məsələn, http://your.api.com/login?username=foo> ) kimi identifikasiya məlumatı verərkən başqa bir problem yaranır: server qeydləri! Çox serverlər sadəcə bütün URL parametrləri daxil olmaqla, hər HTTP sorğunu qeydiyyatdan keçirirlər. Bunun anlamı: serveriniz hacklendiğinde, veritabanınızdan parol hasarlarını koparmaya ehtiyac yoxdur, yalnız server günlük dosyalarına bakmalısınız. Bundan əlavə, təcavüzkar hər bir istifadəçi üçün giriş məlumatını da oxuya bilər. Çözümler:

    • POST (və ya hər hansı digər üsul) istifadə edin və sorğu orqanının içində identifikasiya məlumatını göndərin. Və ya:
    • HTTP başlıqlarında identifikasiya məlumatını göndərin. Bu məlumat adətən server günlük fayllarında görünməməsi səbəbindən. Və ya:
    • Server konfiqurasiyasına baxın və hər bir URL parametrini "parol" (və ya obfuscation, yəni URL girişə login?username=foo> olur login?username=foo> Amma POST metodu ilə yanaşı, bu cür məlumat üçün istək orqanından da istifadə edirəm.

Beləliklə, məsələn:

POST http://your.api.com/authentication olmaq üçün POST http://your.api.com/authentication

Çıxmaq üçün DELETE http://your.api.com/authentication


8. Parolalar və hashing

Doğrulama yalnız gizli açarla işləyir. Əlbəttə ki, bu əsas gizli saxlanılmalıdır. Bunun anlamı:

  • Verilənlər bazasında heç bir zaman parolunuzu dəqiq mətndə saxlamayın. Bir neçə təhlükəsizlik kitabxanası mövcuddur. Mənim fikrimcə, ən yaxşı seçim bcrypt .

  • bcrypt . Hash parolları üçün optimize edilmişdir. O, avtomatik olaraq duz yaradır və bir neçə dəfə parol saxlayır. Bundan əlavə, yaradılan hash line sizə lazım olan hər şeyi ehtiva edir: tur, duz və hash sayını. Yalnız bu bir String saxlamaq lazımdır və əl bir şey yazmaq lazım deyil.

  • Əlbəttə, hər hansı digər güclü hashing kitabxanasından da istifadə edə bilərsiniz. Amma onların əksəriyyəti üçün özəlləşdirmə tətbiq etməli və özünüzdən 1-dən çox tur istifadə etməlisiniz. Bununla yanaşı, siz özünüzü tur, duz və xaş saxlamaq və sonra toplamaq üçün idarə etməlisiniz, lakin bcrypt, məsələn, yalnız bir xətt verməyəcəklər.

  • turlar . Şifrənin nə qədər tez-tez istifadə edilməsi lazımdır. 5000 turdan istifadə edildikdə, hashing funksiyası parol yığımının hash karmasını qaytaracaq. Ümumiyyətlə bunun əsas səbəbi var: CPU gücünə xərclənir! Budur, kimsə haşınıza zərər verməyə çalışsa, 5000 turdan istifadə edərkən 5000 dəfə çoxdur. Ərizə üçün bu əhəmiyyət kəsb etmir: əgər istifadəçi şifrəsini bilirsə, server onu təsdiqləmək üçün 0.0004 ms və ya 2ms qəbul etmədiyini bilməyəcəkdir.

  • yaxşı parollar Şifrə çox sadə olsaydı ən yaxşı hashing funksiyası faydasızdır. Bir lüğət istifadə edərək hacked olsaydı, onu 5000 tur ilə ləğv əgər əhəmiyyətli deyil: bir neçə saat uzun bilər, lakin ay və ya il ola bilər, əgər bir neçə saat nədir? İstifadəçi şifrənizdə adi təkliflər olduğundan əmin olun (aşağı + yuxarı halda + nömrələr + xüsusi simvollar və s.).


9: kabel üzərində şifrəli parol göndərir

HTTPS-yə etibar edə bilmərik (və ya istəmirsinizsə), lakin sistemi daxil edərkən şifrəni parol göndərmək istəmirsinizsə, asimmetrik kriptoqrafiya ( http://en.wikipedia.org/wiki/Public-key_cryptography ) istifadə edə bilərsiniz.

Bu server əsas cüt (fərdi açar və xüsusi açar) yaradır. İctimai açar müştərilərə təqdim edilir, gizli əsas gizli olmalıdır!

Müştəri indi ictimai anahtarı istifadə edərək məlumatları şifreleyebilir və bu məlumatlar yalnız xüsusi açar sahibinin (= server) şifresi ilə şifrələnə bilər.

Bu, (!) Şifrələri verilənlər bazasında saxlamaq üçün istifadə olunmalıdır, çünki serveriniz hacked, hacker şifrələnmiş şifrələri şifresi açmaq üçün xüsusi açar olacaq. Verilənlər bazasında şifrələri saxlamağa baxmayaraq bəzi hashing alqoritmini (məsələn bcrypt) istifadə edin. Başqa bir səbəb isə, kiminsə şifrənizi kəsdiyini düşünsəniz, asanlıqla yeni bir cüt yaratmaqdır.

HTTPS əsasən eyni şəkildə işləyir. Ərizə HTTPS (tövsiyə olunur) istifadə edirsə, təhlükəsizlik baxımından çox fayda ola bilməz. Lakin, yuxarıda göstərildiyi kimi, HTTPS-i hər hansı bir səbəbdən istifadə edə bilmirsinizsə və ya ona etibar etməsəniz, bu, öz təhlükəsiz bir əlaqə yaratmaq yoludur.

Və bir real HTTPS bağlantısının bütün (!) Bağlantıları və bütün məlumatları parol məlumatlarını şifrələməməsini unutmayın. Və hər iki istiqamətdə şifrələir: müştəridən serverə müştəriyə.

377
24 февр. Benjamin M 24 Fevralda təyin etdi. 2013-02-24 15:28 '13 saat 15:28 'də 2013-02-24 15:28
@ 0 cavab