REST API güvenliği JWT vs OAuth'a saklanan jeton


104

REST API'yi korumak için hala en iyi güvenlik çözümünü bulmaya çalışıyorum, çünkü mobil uygulamaların ve API'nin sayısı her geçen gün artıyor.

Farklı kimlik doğrulama yöntemleri denedim, ancak yine de bazı yanlış anlaşılmalar var, bu yüzden daha deneyimli birisinin tavsiyesine ihtiyacım var.

Tüm bunları nasıl anladığımı anlatayım. Bir şeyi yanlış anlarsam, lütfen bana bildirin.

REST API genel olarak WEB kadar genel olarak durumsuz olduğu sürece, her bir talepte bazı çerezler göndermemiz gerekir (çerezler, token ....). Kullanıcı kimliğini doğrulamak için yaygın olarak kullanılan üç mekanizmayı biliyorum

  1. HTTPS ile belirteci. Bu yaklaşımı HTTPS ile yeterince iyi kullandım. Eğer kullanıcı doğru şifreyi ve giriş bilgisini verirse, cevap olarak token alacak ve daha sonraki istekler için onu kullanacaktır. Token, sunucu tarafından üretilir ve örneğin ayrı tabloda veya kullanıcı bilgilerinin saklandığı tabloda depolanır. Bu nedenle, her istek sunucusu için kullanıcının belirteç olup olmadığını ve veritabanındaki ile aynı olup olmadığını kontrol eder. Her şey oldukça basit.

  2. JWT Token. Bu belirteç kendi kendini tanımlayıcı niteliktedir, belirteç kendisi hakkında gerekli tüm bilgileri içerir, kullanıcı örneğin son kullanma tarihini veya başka bir talebi değiştiremez, çünkü bu belirteç gizli anahtarla sunucu tarafından üretilir (imzalanır). Bu da açık. Ama şahsen benim için büyük bir sorun belirteci nasıl geçersiz kılacağımı.

  3. OAuth 2. Doğrudan sunucu ile müşteri arasında iletişim kurulurken bu yaklaşımın neden kullanılması gerektiğini anlamıyorum. Anladığım kadarıyla OAuth sunucusu, diğer uygulamaların şifre ve giriş yapmadan kullanıcı bilgilerine erişmesine izin vermek için sınırlı kapsamlı bir simge yayınlamak için kullanılır. Bu, sosyal ağlar için mükemmel bir çözümdür, kullanıcı bir sayfaya kaydolmak istediğinde, sunucu, örneğin twitter veya facebook'tan kullanıcı bilgisi alma izni alabilir ve kayıt alanlarını kullanıcı verileri vb. İle doldurabilir.

Çevrimiçi mağaza için mobil istemciyi düşünün.

İlk soru ilk tip belirteci yerine JWT'yi mi tercih etmeliyim? Mobil istemcide oturum açma / kapatma kullanıcısına ihtiyacım olduğu sürece, bir yere veya JWT durumunda depolamam gerekiyor, belirtecin oturumu kapatması gerekiyor. Geçersiz bir liste (kara liste) oluşturmak için belirteci geçersiz kılmak için farklı yaklaşımlar kullanılır. Hmm. Tablo / dosya, belirtecin tabloda depolanıp kullanıcılarla ilişkilendirilip oturumu kapatmadan kaldırılmasından çok daha büyük bir boyuta sahip olacaktır.

Peki JWT belirtecinin faydaları nelerdir?

OAuth hakkındaki ikinci soru, sunucumla doğrudan iletişim halinde kullanmam gerekir mi? İstemci ve sunucu arasında yalnızca belirteç vermek için bir katman daha kullanılmasının amacı nedir, ancak iletişim oauth sunucusu ile değil, ana sunucu ile olacaktır. Anladığım kadarıyla OAuth sunucusu, yalnızca kullanıcıya özel bilgilere erişmek için üçüncü taraf uygulama izinleri (belirteçleri) vermekten sorumludur. Ancak mobil istemci başvurum üçüncü taraf değil.


Teşekkürler, bunu son zamanlarda merak ediyordum. Oturum yönetimi (Beaker) ile gittim ve bir saat sonra oturum belirteçlerini sildim. Oauth doğru uygun görünmüyordu.
JasTonAChair

Yanıtlar:


86

İlk vakayı düşünün. Her müşteri, oturum süresi boyunca devam eden rastgele bir kimlik alır - bu da isterseniz birkaç gün sürebilir. Ardından, o oturumla ilgili bilgileri sunucu tarafında bir yerde saklarsınız. Bir dosyada veya bir veritabanında olabilir. Diyelim ki kimliği bir çerez üzerinden geçirdiniz, ancak URL'yi veya bir HTTP başlığını kullanabilirsiniz.

Oturum kimlikleri / Çerezler

Artıları:

  • Hem istemciyi hem de sunucuyu kodlamak kolaydır.
  • Birisi oturumu kapattığında oturumu imha etmek kolaydır.

Eksileri:

  • Sunucu tarafı, istemcinin oturumu kapatmadığı, süresi dolmuş oturumları silmeye ihtiyaç duyar.
  • Her HTTP isteği, veri deposuna bir arama yapılmasını gerektirir.
  • Depolama gereksinimleri, daha fazla kullanıcının aktif oturumları olduğundan, artar.
  • Birden fazla ön uç HTTP sunucusu varsa, depolanan oturum verilerine hepsinin erişebilmesi gerekir. Bu, bir sunucuya kaydetmekten biraz daha fazla iş olabilir. En büyük sorun, veri deposunun tek bir başarısızlık noktası haline gelmesi ve bir tıkanıklık haline gelmesidir.

JSON Web Jetonları (JWT)

İkinci durumda, veriler sunucu yerine geçirilen bir JWT'de saklanır.

Artıları:

  • Sunucu tarafı depolama sorunları gitti.
  • İstemci tarafı kodu kolaydır.

Eksileri:

  • JWT boyutu, bir oturum kimliğinden daha büyük olabilir. Her HTTP isteğine dahil edildiğinden ağ performansını etkileyebilir.
  • JWT'de depolanan veriler müşteri tarafından okunabilir. Bu bir sorun olabilir.
  • Sunucu tarafında, JWT'leri oluşturmak, doğrulamak ve okumak için kod gerekir. Zor değil, ancak bir öğrenme eğrisi var ve güvenlik buna bağlı.

    İmza anahtarının bir kopyasını alan herkes JWT oluşturabilir. Bunun ne zaman olacağını bilmiyor olabilirsiniz.

    Bazı kütüphanelerde "none" algoritması ile imzalanmış herhangi bir JWT'yi kabul eden bir hata vardı, böylece herkes sunucunun güveneceği JWT'ler yaratabilecekti.

  • Bir JWT'yi sona ermeden önce iptal etmek için bir iptal listesi kullanmanız gerekir. Bu, kaçınmaya çalıştığınız sunucu tarafındaki depolama sorunlarına geri dönmenizi sağlar.

OAuth

Genellikle OAuth, kimlik doğrulama için kullanılır (yani kimlik), ancak kullanıcının satın aldığı ve indirme hakkına sahip olduğu bir içerik listesi gibi diğer verileri paylaşmak için kullanılabilir. Ayrıca, üçüncü tarafça depolanan verilere yazma izni vermek için de kullanılabilir. Kullanıcıların kimliğini doğrulamak için OAuth'u kullanabilir ve ardından oturum verileri için sunucu tarafında depolamayı veya JWT'yi kullanabilirsiniz.

Artıları:

  • Kullanıcıların şifrelerini kaydetmesi veya sıfırlaması için kod yok.
  • Doğrulama bağlantısı olan bir e-posta göndermek ve ardından adresi doğrulamak için kod yok.
  • Kullanıcıların başka bir kullanıcı adı ve şifre öğrenmesi / yazması gerekmez.

Eksileri:

  • Kullanıcılarınızın servisinizi kullanması için üçüncü taraflara güveniyorsunuz. Servisleri düşerse veya keserse, başka bir şey bulmanız gerekir. Örn: kimlikleri "foo@a.com" den "bar@b.com" a değiştirilirse, kullanıcının hesap verilerini nasıl geçirirsiniz?
  • Genellikle her sağlayıcı için kod yazmanız gerekir. örneğin Google, Facebook, Twitter.
  • Siz veya kullanıcılarınızın gizlilik endişeleri olabilir. Sağlayıcılar, kullanıcılarının hangisinin hizmetinizi kullandığını bilir.
  • Sağlayıcıya güveniyorsunuz. Sağlayıcının, bir kullanıcı için geçerli olan jetonları başkalarına vermesi mümkündür. Bu yasal amaçlar için olabilir veya olmayabilir.

Çeşitli

  • Hem oturum kimlikleri hem de JWT'ler birden fazla kullanıcı tarafından kopyalanabilir ve kullanılabilir. İstemci IP adresini bir JWT'de saklayabilir ve doğrulayabilirsiniz ancak istemcilerin kablosuz ağdan hücresel telefona dolaşımını engeller.

Cevabınıza eklemek için, kullanıcı, genellikle sosyal ağ siteleri veya google ile ilişkili olmayan veya bunlarla bağlantılı olmayan şirket hesaplarını kullanarak kaydolmak istediğinde yararlı olmayabilir.
Aftab,

5
Bunun neden kabul edilen cevap olduğunu bilmiyorum? sadece başka bir şekilde soru reform, gerçek soruya cevap vermez
amd

1
Diyorsunuz: "JWT'de depolanan veriler müşteri tarafından okunabilir. Bu bir sorun olabilir. Eğer bu bir sorunsa neden JWE kullanmıyorsunuz?
Silver

Bu cevap elmaları ve portakalları karıştırır. Bunları OAuth 2.0 ("yetkilendirme" özelliği) ile karşılaştırmamalısınız. OP'nin bilmesi gereken şey şudur: "Kaynak Sahibi Parola Akışı" - bu bir hibe olarak kimlik doğrulamasıdır.
Onur Yıldırım

5

Orijinal belirteci neden geçersiz kılmanız gerektiğini kendinize sorun.

Bir kullanıcı oturum açar, bir belirteç oluşturulur ve uygulamadan çıkar.

Kullanıcı oturumu kapatmaya basar, yeni bir belirteç oluşturulur ve orijinal belirleyicinin yerini alır. Bir kez daha, her şey yolunda.

Her iki jetonun takıldığı dava için endişeleniyor gibisin. Kullanıcı oturumu kapatır ve daha sonra bir şekilde oturum açmış jetonunu kullanarak bir istek yaparsa. Bu senaryo ne kadar gerçekçi? Çıkış sırasında sadece bir sorun mu var yoksa birden fazla belirteçlerin sorun olabileceği birçok olası senaryo var mı?

Ben kendimin endişelenmeye değer olduğunu düşünmüyorum. Birisi şifreli https verilerinizi yakalayıp çözüyorsa, çok daha büyük sorunlarınız olur.

Orijinal belirteç üzerine bir son kullanma süresi koyarak kendinize biraz ek koruma sağlayabilirsiniz. Bu yüzden eğer çalınmaya başlanırsa ya da bir şey olursa o zaman kısa bir süre için iyi olur.

Aksi halde, sunucu hakkında durum bilgisine sahip olmanız gerektiğini düşünüyorum. Belirteçleri kara listeye almayın, bunun yerine geçerli belirteç imzasını beyaz listeye alın.


2
Bazı müşterilerinizin kötü niyetli olduğunu varsayıyorsanız, bir oturumun kopyalanacağını ve yeniden kullanılacağını görmek kolaydır ve bunu sunucuda karşılamanız gerekir.
Michael Shaw,

1
Kötü bir fikir, bu daha sonra bilgisayar korsanı tarafından kullanılabilir veya zorla sadece kaba ...
CROSP 5:15

2
Bir kullanıcının diğer tüm cihazlardan çıkış yapmak istediğini, JWT kullanmak mümkün olmadığını hayal edin.
amd

@amd mümkün değil mi? Nonce = (random) eklersem ve kullanıcı oturumu kapatırsa, nonce'i değiştirirseniz. Basit ve etkili görünüyor.
Simon B.

3

Bahsettiğiniz JWT sorunlarını, kullanıcı ile birlikte bir tuz değeri depolayarak ve tuzu kullanıcı belirtecinin bir parçası olarak kullanarak halledebilirsiniz. Ardından belirteci geçersiz kılmanız gerektiğinde, tuzu değiştirin.

Birkaç yıl geçtiğini biliyorum ama şimdi bunu gerçekten farklı yapardım. Sanırım erişim belirteçlerinin bir saat kadar kısa ömürlü olmalarını sağlayacağımı düşünüyorum. Ayrıca sunucuda durum bilgisi olan yenileme belirteçleri kullanacağımdan eminim ve sonra birinin oturumunu sonlandırmak istediğimde, yenileme belirtecini sunucudan kaldırarak iptal etmem gerekir. Sonra bir saat sonra, kullanıcı oturumu kapatır ve tekrar erişim kazanmak için tekrar giriş yapması gerekirdi.


4
Ancak bu durumda yine devlet dolgulu hale gelir, bu nedenle tuz oluşturmanın veya başka bir yaklaşımı kullanmanın nedeni nedir, tablodaki basit mağaza
işaretini alabilir

2
Ayrıca zamana bağlı olarak geçersiz kılabilirsiniz.
RibaldEddie

Bu durumda son kullanma süresi arasındaki fark nedir? Kullanıcı mobil istemciden çıkış yapmak istediğinde zamana bağlı olarak jetonu nasıl geçersiz kılabilirim? Bu durumda API durumsuz olması mümkün görünmüyor. Bundan daha uygun ve güvenli çözüm nedir?
CROSP

2
Tek bir cihazdan çıkmak için en uygun olanı, tuza ek olarak bir müşteri kimliği kullandığınızdan emin olmaktır. Oauth-jwt hamilinin belirteç özelliklerine bir bakış için bakmanı öneriyorum.
RibaldEddie

Cevabınız için teşekkürler, ama neden bu durumda OAuth'u kullanmalıyım anlamıyorum.
CROSP
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.