Mobil uygulamalar için API oluşturma - Kimlik Doğrulama ve Yetkilendirme


189

genel bakış

Benim uygulama için bir (REST) ​​API oluşturmak için arıyorum. İlk / birincil amaç mobil uygulamalar (iPhone, Android, Symbian, vb.) Tarafından tüketim içindir. Web tabanlı API'ler için kimlik doğrulama ve yetkilendirme için farklı mekanizmalar araştırıyorum (diğer uygulamaları inceleyerek). Başımı temel kavramların çoğuna sartım, ancak hala birkaç alanda rehberlik arıyorum. Yapmak istediğim son şey tekerleği yeniden icat etmek, ancak kriterlerime uyan herhangi bir standart çözüm bulamıyorum (ancak kriterlerim yanlış yönlendirildi, bu yüzden de eleştirmekten çekinmeyin). Ayrıca, API'yi tüketen tüm platformlar / uygulamalar için aynı olmasını istiyorum.

OAuth

Sunulan ilk çözüm olacağını bildiğim için devam edeceğim ve oAuth'a itirazımı atacağım. Mobil uygulamalar (veya daha özel olarak web dışı uygulamalar) için, kimlik doğrulaması için uygulamadan ayrılmak (bir web tarayıcısına gitmek) yanlış görünüyor. Ayrıca, tarayıcının geri aramayı uygulamaya (özellikle çapraz platform) geri döndürmesinin bir yolu (farkındayım) yoktur. Bunu yapan bir kaç uygulama biliyorum, ama yanlış geliyor ve uygulama UX'da mola veriyor.

Gereksinimler

  1. Kullanıcı uygulamaya kullanıcı adı / şifre girer.
  2. Her API çağrısı arayan uygulama tarafından tanımlanır.
  3. Genel gider minimumda tutulur ve kimlik doğrulaması geliştiriciler için sezgiseldir.
  4. Mekanizma hem son kullanıcı (giriş kimlik bilgileri gösterilmez) hem de geliştirici (uygulama kimlik bilgileri gösterilmez) için güvenlidir.
  5. Mümkünse, https gerektirmez (kesinlikle zor bir gereklilik değildir).

Uygulamayla İlgili Mevcut Düşüncelerim

Harici bir geliştirici bir API hesabı isteyecektir. Apikey ve apisecret alacaklar. Her istek en az üç parametre gerektirir.

  • apikey - geliştiriciye kayıt sırasında verilen
  • timestamp - belirli bir apikey için her mesaj için benzersiz bir tanımlayıcı olarak iki katına çıkar
  • karma - zaman damgasının karma değeri + apisecret

Apikey, talebi veren uygulamayı tanımlamak için gereklidir. Zaman damgası, oauth_nonce öğesine benzer şekilde davranır ve tekrar saldırılarını önler / azaltır. Karma, söz konusu isteğin sahibinin isteğinin gerçekte yapılmasını sağlar.

Kimliği doğrulanmış istekler için (bir kullanıcı adına yapılanlar), hala bir erişim_düzeni yolu veya bir kullanıcı adı ve parola karma combo ile gitmek arasında kararsızım. Her iki durumda da, bir noktada bir kullanıcı adı / şifre kombinasyonu gerekir. Bu durumda, birkaç bilgi parçasından oluşan bir karma (apikey, apisecret, zaman damgası) + şifre kullanılır. Bu konuda geri bildirim almak isterim. FYI, parolaları karma olmadan sistemime kaydetmediğim için önce parolayı hash etmek zorunda kalacaklardı.

Sonuç

Bilginize, bu genel olarak API'nın nasıl oluşturulacağı / yapılandırılacağı, sadece bir uygulama içinden kimlik doğrulama ve yetkilendirmenin nasıl ele alınacağı konusunda bir talep değildir.

Rastgele Düşünceler / Bonus Sorular

Yalnızca isteğin bir parçası olarak bir apikey gerektiren API'ler için, apikey sahibi dışında birisinin apikey'i görmesini (açık bir şekilde gönderildiği için) ve kullanım sınırlarını aşmak için aşırı istekler almasını nasıl önlersiniz? Belki de bunu biraz düşündüm, ama apikey sahibine bir isteğin doğrulandığını doğrulayacak bir şey olmamalı mı? Benim durumumda, apisecret'in amacı buydu, asla karma olmadan gösterilmez / iletilmez.

Hashlerden bahsetmişken, md5 vs hmac-sha1 ne olacak? Tüm değerlerin yeterince uzun verilerle (yani apisecret) birleştirilmesi gerçekten önemli mi?

Önceden kullanıcılarımın şifre karmasına bir kullanıcı / satır tuzu eklemeyi düşünüyordum. Bunu yapsaydım, uygulama, kullanılan tuzu bilmeden nasıl eşleşen bir karma oluşturabilirdi?


1
Birkaç yorum / öneri almayı umuyordum. Soru çok belirsiz / belirsiz mi?
jsuggs

6
soru mükemmel ama neredeyse 2 yıl sonra, oauth uygulamaları gizli görünüyor ... tam olarak yukarıda tartıştıklarınızı başarmak için en zor zamanlarım var. i ek bir boyutu var: ben bir loginName / şifre çifti kullanmak istemiyorum - ben android / ios (symbian WWF tarafından "neredeyse tükenmiş bir tür" ilan edildi) google kimlik doğrulama kullanmak istiyorum ve ben geliştirmek için reddediyorum windows mobile (bu gün ne derse desinler).
tony gil

8
herkesin oauth 2.0 ive henüz önerdiği kadar saçma, açık, basit bir öğretici veya adımları, gereksinimleri, yapılacaklar ve donts vb açıklamak için ortak İngilizce kullanan bir örnek bulmak için ....
ChuckKelly

2
Bu özel OAuth2.0 akışını (Kaynak Sahibi Parola Akışı) okuyun. Web sitesine yönlendirme yok. techblog.hybris.com/2012/06/11/…
Franklin

1
Ben de aynı cevabı arıyorum. Son zamanlarda yazılmış iyi bir makale buldum. Umarım bu yardımcı olur. stormpath.com/blog/the-ultimate-guide-to-mobile-api-surity
Yeni

Yanıtlar:


44

Projelerimde bunun giriş bölümünü yapmayı düşünüyorum:

  1. giriş yapmadan önce kullanıcı login_token sunucudan . Bunlar istek üzerine üretilir ve sunucuda saklanır ve muhtemelen sınırlı bir kullanım ömrüne sahiptir.

  2. Uygulamaya giriş yapmak için kullanıcı parolasının karma değerini hesaplar, daha sonra login_tokenbir değer elde etmek için parolayı hash eder ,login_token ve kombine karma .

  3. Sunucu login_token, oluşturduğu olanı denetler ve geçerli login_tokens listesinden kaldırır . Sunucu daha sonra kullanıcının parolasının kayıtlı karmasını ile login_tokenbirleştirir ve gönderilen birleşik belirteçle eşleşmesini sağlar. Eşleşirse, kullanıcı kimliğinizi doğruladınız.

Bunun avantajları, kullanıcının parolasını hiçbir zaman sunucuda saklamamanız, parola hiçbir zaman net olarak geçilmemesi, parola karmasının yalnızca hesap oluşturma işleminde net olarak geçmesi (bunun etrafında yollar olabilir) ve olması gerekir. login_tokenkullanımdaki DB'den kaldırıldığı için tekrar saldırılarına karşı güvenlidir .


Teşekkürler, uygulama tarafında şifre karma hakkında eklemek için unuttum. Kullanıcılarımın şifrelerini açık bir şekilde saklamıyorum (saklamadan önce karma).
jsuggs

2
Bu yöntemin bir dezavantajı görüyorum: tuzlu parolaları DB'de depolayamazsınız. Eğer saldırganlar DB'nize ellerini koyarlarsa, herhangi bir şifre çözme yapmaları gerekmez. Parola karması bu şemadaki gerçek parola olduğundan.
sigod

2
@sigod Haklısın. Ben orada temel bir ikilik olduğunu düşünüyorum rağmen - ya taşıma güven ya da depolama güvenmeniz gerekir. Tuzlu şifreler kullanan giriş sistemleri, taşıma katmanına güvenir ve bu nedenle şifreyi açık bir şekilde kullanıcıdan kimlik doğrulama sistemine geçirir. Bu durum taşıma katmanına güvenmiyor (bence bu, hedeflediğim platformun SHTTP için kötü desteğe sahip olmasıydı). Taşıma katmanına güveniyorsanız, başka ödünleşmeler yapabilirsiniz.
Michael Anderson

3 problemim var: 1) Kullanıcının şifresi asla sunucuda saklanmıyor mu? 2. adımda karma kullanıcı şifresini sakladığını söylemiştiniz. 2) Kullanıcı şifresi asla anlaşılır bir şekilde iletilmez. Ama aslında istemcide hashed ve daha sonra sunucu üzerinde hashed şifre ile karşılaştırıldığında, neredeyse açık ve geçen saklamak aynıdır, bunu yapmanın anlamı nedir? 3) Bu yöntem, saldırganın Kerckhoffs prensibini ihlal eden ve gerçekten güvensiz hale getiren login_token + şifresinin nasıl karma olduğunu bilmediğini varsayar.
Tamer Shlash

14

Bu bir sürü soru, sanırım birkaç kişi sonuna kadar okumayı başaramadı :)

Web hizmeti kimlik doğrulaması konusundaki deneyimim, insanların genellikle ondan daha fazla olduğunu ve sorunların yalnızca bir web sayfasında karşılaşacağınızla aynı olduğudur. Olası çok basit seçenekler, oturum açma adımı için https, bir jeton döndürme, gelecekteki isteklere dahil edilmesini gerektirecektir. Ayrıca http temel kimlik doğrulamasını kullanabilir ve başlıkta bir şeyler iletebilirsiniz. Ek güvenlik için, belirteçleri sık sık döndürün / sona erdirin, isteklerin aynı IP bloğundan gelip gelmediğini kontrol edin (mobil kullanıcılar hücreler arasında hareket ederken dağınık olabilir), API anahtarı veya benzeri ile birleştirin. Alternatif olarak, kullanıcının kimliğini doğrulamadan önce oauth'un "istek anahtarı" adımını yapın (birisi bunu önceki bir yanıtta önerdi ve iyi bir fikir) ve erişim belirtecini oluşturmak için bunu gerekli bir anahtar olarak kullanın.

Henüz kullanmadığım bir alternatif ama oAuth'a cihaz dostu bir alternatif olarak çok şey duydum xAuth . Bir göz atın ve kullanırsanız, izlenimlerinizin ne olduğunu duymak gerçekten ilgimi çeker.

Karma için, sha1 biraz daha iyidir, ancak takılmayın - cihazlar ne olursa olsun (ve hızlı bir şekilde performans açısından) uygulama muhtemelen iyidir.

Umarım bu yardımcı olur, iyi şanslar :)


Yanıt için teşekkürler. Ben xAuth içine bakıyordum ve ben API ile etkileşim için daha standartlaştırılmış bir süreç için yapar bir oAuth yükleme ile sona erebilir, böylece ben gidebilirim yolu olabilir.
jsuggs

9

Peki peşinizde olan, bir mobil uygulamanın kimlik doğrulama ve yetkilendirme yönlerini ele alacak bir tür sunucu tarafı kimlik doğrulama mekanizmasıdır?

Durum böyle olduğunu varsayarsak, o zaman aşağıdaki gibi yaklaşırdım (ama sadece bir Java geliştiricisiyim, bu yüzden bir C # adam farklı yapardı):

RESTful kimlik doğrulama ve yetkilendirme hizmeti

  1. Bu, gizli dinlemeyi önlemek için yalnızca HTTPS üzerinde çalışacaktır.
  2. RESTEasy , Spring Security ve CAS birleşimlerine dayanacaktır. (birden fazla uygulamada tek oturum açma için) .
  3. Hem tarayıcılarla hem de web özellikli istemci uygulamalarıyla çalışır
  4. Kullanıcıların ayrıntılarını düzenlemesine izin veren web tabanlı bir hesap yönetimi arayüzü ve yetkilendirme düzeylerini değiştirmek için yöneticiler (belirli uygulamalar için) olacaktır.

İstemci tarafı güvenlik kitaplığı / uygulaması

  1. Desteklenen her platform için (örn. Symbian, Android, iOS vb.) Güvenlik kütüphanesinin platformun ana dilinde (örn. Java, ObjectiveC, C vb.) Uygun bir uygulamasını oluşturun.
  2. Kütüphane, belirtilen platform için mevcut API'ları kullanarak HTTPS istek oluşumunu yönetmelidir (örn. Java, URLConnection vb. Kullanır)
  3. Genel kimlik doğrulama ve yetkilendirme kitaplığı tüketicileri (çünkü hepsi bu kadar) belirli bir arayüze kodlama yapacak ve eğer değişirse mutlu olmayacak, bu yüzden çok esnek olduğundan emin olun. Spring Security gibi mevcut tasarım seçeneklerini takip edin.

Peki şimdi 30.000ft'lik görüş tamamlandığında bunu nasıl yapıyorsunuz? Bir tarayıcı istemcisi ile sunucu tarafında listelenen teknolojilere dayalı bir kimlik doğrulama ve yetkilendirme sistemi oluşturmak o kadar zor değil. HTTPS ile birlikte, çerçeveler, kimlik doğrulama işlemi tarafından oluşturulan ve kullanıcı bir şey yapmak istediğinde kullanılan paylaşılan bir belirteci (genellikle çerez olarak sunulur) temel alan güvenli bir işlem sağlar. Bu simge, herhangi bir istek gerçekleştiğinde istemci tarafından sunucuya sunulur.

Yerel mobil uygulama söz konusu olduğunda, aşağıdakileri yapan bir çözüm peşindesiniz:

  1. İstemci uygulaması, yöntem çağrılarına çalışma zamanı erişimini denetleyen tanımlı bir Erişim Denetim Listesi'ne (ACL) sahiptir. Örneğin, belirli bir kullanıcı bir yöntemden bir koleksiyonu okuyabilir, ancak ACL'si yalnızca adında Q olan nesnelere erişime izin verir, bu nedenle koleksiyondaki bazı veriler güvenlik önleyicisi tarafından çekilir. Java'da bu basittir, arama kodunda Spring Security ek açıklamalarını kullanır ve uygun bir ACL yanıt süreci uygularsınız. Diğer dillerde, kendi başınızasınız ve muhtemelen güvenlik kitaplığınızı çağıran ortak güvenlik kodu sağlamanız gerekecektir. Dil AOP'yi (En Boy Odaklı Programlama) destekliyorsa, bu durum için sonuna kadar kullanın.
  2. Güvenlik kitaplığı, yetkilendirmelerin tam listesini geçerli uygulama için özel belleğinde önbelleğe alır, böylece bağlantıda kalması gerekmez. Oturum açma oturumunun uzunluğuna bağlı olarak, bu bir daha asla tekrarlanmayan tek seferlik bir işlem olabilir.

Ne yaparsan yap, kendi güvenlik protokolünü icat etmeye çalışma veya belirsizliği kullanarak güvenliği kullanmayın. Bunun için hiçbir zaman şu anda mevcut ve ücretsiz olanlardan daha iyi bir algoritma yazamazsınız. Ayrıca, insanlar iyi bilinen algoritmalara güvenir. Dolayısıyla, güvenlik kitaplığınızın SSL, HTTPS, SpringSecurity ve AES şifreli tokenlerin bir kombinasyonunu kullanarak yerel mobil uygulamalar için yetkilendirme ve kimlik doğrulaması sağladığını söylüyorsanız, hemen piyasada kredibiliteye sahip olursunuz.

Umarım bu yardımcı olur ve girişiminizde iyi şanslar. Daha fazla bilgi isterseniz, bana bildirin - Spring Security, ACL'ler ve benzerlerine dayanan birkaç web uygulaması yazdım.


Teşekkürler, iyi bilgi. Birkaç soru. Birincisi, gizli dinleme kabul edilebilirse (bunun olup olmadığından emin değilim, aklımdaki başvurumun gerçek kişisel / değerli bilgileri yok, ancak mantığım değişecekse) HTTPS gerçekten gerekli mi?
jsuggs

İsterseniz genel sistemi HTTPS dışında da çalıştırabilirsiniz. HTTPS yalnızca gizli bilgileri korumak içindir, bu nedenle kimlik doğrulama aşamasında bunu kullanıcı adınızın / şifrenizin / sırrınızın gizli tutulduğunu garanti etmek için HTTPS aracılığıyla yapacağınızı varsayarım. Jeton yanıtta teslim edildikten sonra, akışta yer alan bilgilerin (elde edilmesi gereken kimlik doğrulaması) kulak misafiri korumaya ihtiyaç duymadığı durumlarda daha fazla talep yapılabilir.
Gary Rowe

Ayrıca, CAS kimlik doğrulama protokolünün bu açıklaması yararlı olabilir: jasig.org/cas/protocol
Gary Rowe

9

Twitter, xAuth olarak adlandırdıkları bir varyasyonu destekleyerek oAuth'taki harici uygulama sorununu çözdü . Ne yazık ki, bu isimle başka şemaların çokluğu var, bu yüzden sıralamak kafa karıştırıcı olabilir.

Protokol , istek belirteci aşamasını atlaması ve bir kullanıcı adı ve parola alındığında hemen bir erişim belirteci çifti yayınlaması dışında oAuth'tur. ( Buradaki E adımından başlayarak .) Bu ilk istek ve yanıtın sağlanması gerekir- kullanıcı adını ve şifreyi düz metin olarak gönderiyor ve erişim belirteci ile gizli belirteci geri alıyor. Erişim belirteci çifti yapılandırıldıktan sonra, ilk belirteç alışverişinin oAuth modeli üzerinden mi yoksa xAuth modelinin oturumun geri kalanı için hem istemci hem de sunucu ile ilgisi yoktur. Bunun avantajı, mevcut oAuth altyapısından yararlanabilmeniz ve mobil / web / masaüstü uygulamaları için neredeyse aynı uygulamaya sahip olmanızdır. Ana dezavantaj, uygulamanın istemcinin kullanıcı adı ve şifresine erişmesine izin verilmesidir, ancak gereksinimleriniz bu yaklaşımı zorunlu kılıyor gibi görünmektedir.

Her halükarda, sezgilerinize ve buradaki diğer bazı cevaplayıcıların fikirlerine katılıyorum: sıfırdan yeni bir şey inşa etmeye çalışmayın. Güvenlik protokollerinin başlatılması kolay olabilir, ancak her zaman başarılı olmak zordur ve daha kıvrımlı hale geldiklerinde, üçüncü taraf geliştiricilerin bunlara karşı uygulama yapma olasılıkları azalır. Varsayımsal protokolünüz o (x) Auth - api_key / api_secret, nonce, sha1 karma işlemine çok benzer - ancak geliştiricilerinizin kendi kütüphanelerini döndürmesi gereken birçok kütüphaneden birini kullanmak yerine.


2
Ben de 'istek atlamak belirteci' bitiş noktası oAuth 2 olacak gibi görünüyor, o geçerli taslak "şifre" erişim hibe türü olarak listelenen belirtmek gerekir. Bkz. Bölüm 4.1.2: tools.ietf.org/html/draft-ietf-oauth-v2-10#section-4.1.2
lantius

Lonra'dan bahsettiğim gibi, xAuth'a daha çok bakıyorum ve özellikle sonunda bahsettiğiniz nedenlerden dolayı ... geliştiriciler, "iyi bir şey" olan API'm ile etkileşim kurmak için "raftan" oAuth araçlarını / kütüphanelerini yapabilir .
jsuggs

6

Partiye çok geç kaldım ama bu konuyla ilgilenen herkes için dikkate almak için bazı ek noktalar atmak istedim. Mobil API güvenlik çözümleri yapan bir şirkette çalışıyorum ( yaklaşık ) bu yüzden bu alanın tamamı benim ilgim ile kesinlikle alakalı.

Başlangıç ​​olarak, bir mobil API güvenliğini sağlamaya çalışırken göz önünde bulundurmanız gereken en önemli şey sizin için ne kadar değerli olduğudur. . Bir banka için doğru çözüm, sadece eğlenmek için bir şeyler yapan biri için doğru çözümden farklıdır.

Önerilen çözümde en az üç parametrenin gerekli olacağını belirtiyorsunuz:

  • apikey - kayıt sırasında geliştiriciye verilir
  • timestamp - belirli bir apikey için her mesaj için benzersiz bir tanımlayıcı olarak iki katına çıkar
  • karma - zaman damgasının karma değeri + apisecret

Bunun anlamı, bazı API çağrıları için herhangi bir kullanıcı adı / şifre gerekmemesidir. Bu, bir girişi zorlamak istemediğiniz uygulamalar için yararlı olabilir (örneğin çevrimiçi mağazalarda gezinme).

Bu, kullanıcı kimlik doğrulamasından biri için biraz farklı bir sorundur ve daha çok yazılımın kimlik doğrulaması veya tasdiki gibidir. Kullanıcı yok, ancak yine de API'nize kötü amaçlı erişim olmadığından emin olmak istiyorsunuz. Böylece, trafiği imzalamak ve API'ya erişen kodu orijinal olarak tanımlamak için API sırrınızı kullanırsınız. Bu çözümle ilgili potansiyel sorun, uygulamanın her sürümünde sırrı vermeniz gerektiğidir. Birisi sırrı çıkarabilirse, API'nizi kullanabilir, yazılımınızı taklit eder, ancak istediği şeyi yapar.

Bu tehdide karşı koymak için, verilerin ne kadar değerli olduğuna bağlı olarak yapabileceğiniz bir sürü şey vardır. Gizleme , sırrı çıkarmayı zorlaştırmanın basit bir yoludur. Bunu sizin için yapacak, Android için daha fazla araç var, ancak yine de hashınızı üreten bir kodunuz olmalı ve yeterince yetenekli bir kişi her zaman doğrudan hash yapan işlevi çağırabilir.

Oturum açma gerektirmeyen bir API'nin aşırı kullanımına karşı önlem almanın bir başka yolu da trafiği kısmak ve şüpheli IP adreslerini potansiyel olarak tanımlamak ve engellemek. Gitmek istediğiniz çaba büyük ölçüde verilerinizin ne kadar değerli olduğuna bağlı olacaktır.

Bunun ötesinde günlük işimin alanına kolayca girmeye başlayabilirsiniz. Her neyse, önemli olduğunu ve işaretlemek istediğini düşündüğüm API'leri korumanın başka bir yönü.

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.