PostgreSQL'deki finansal uygulama için kimlik doğrulama yaklaşımı seçimi


15

Önce biraz arka plan.

LedgerSMB projesi, PostgreSQL üzerinde çalışan açık kaynaklı bir finansal muhasebe yazılımı projesidir. Kullanıcı tanımlı işlevlerde, program nesnesi yöntemleri ile veritabanı davranışı arasında ana eşleme aracı işlevi gören çok büyük miktarda iş mantığı uyguluyoruz. Şu anda veritabanı kullanıcılarını kısmen seçim yoluyla kimlik doğrulama kullanıcıları olarak kullanıyoruz (bu, merkezi güvenlik mantığına izin verir, böylece diğer araçlar yazılabilir ve kullanıcılara verilen izinleri yeniden kullanabilir) ve kısmen gereklilikle (SQL-Ledger'den çatallandıktan sonra) güvenliği bu kod tabanına uyarlamak için pek çok seçenek yoktu).

Bu bize PostgreSQL'in LDAP'den Kerberos 5'e erişebildiği makul sayıda tek oturum açma seçeneğine erişim sağlıyor. Parolalar söz konusu olduğunda PAM bile kullanabiliriz. Ayrıca, diğer uygulamalarla tümleştirirken veya diğer istemci arabirimlerine izin verirken izinleri yeniden kullanmamıza izin verir. Bir finansal muhasebe uygulaması için bu net bir kazanç gibi görünüyor.

Belirgin maliyetler söz konusudur. Web uygulaması için, desteklenebilecek http kimlik doğrulaması türleriyle çok sınırlıyız. Örneğin DIGEST tamamen çıktı. BASIC işe yarıyor ve KRB5'i yeterince kolayca uygulayabiliriz (bunu 1.4 için desteklemeyi ve kutudan çıkarmayı planlıyorum). Çok güçlü kimlik doğrulama önlemleri doğrudan bu konuda düzgün bir şekilde yönetilemez, ancak gerektiğinde bunları saklayabiliriz (örneğin, kullanıcı adı ve belirli bir kök ca ile eşleşen bir cn içeren BASIC + istemci tarafı SSL sertifikası).

Aynı zamanda, çoğunlukla geliştirme kalabalığından ve bazen de uygulamanın veritabanı değil güvenlik bariyeri olması gerektiğini söyleyen dba'lardan oldukça fazla eleştiri aldık. Benim görüşüme göre, daha küçük bir güvenlik çevresi genel olarak daha iyi, iş mantığı ve güvenlik mantığının yeniden kullanılması bir arada ve güvenlik mantığını tekrar aynı düzeyde kullanmadan iş mantığının yeniden kullanılmasının tehlikeli olduğunu gösteriyor. programın.

Burada büyük ödünleşmelerim eksik mi? Düşünmediğim bir şey var mı?


1
Pgsql-genel posta listesine çapraz postalanmıştır. Buradan başlayan konuya bakın .
Craig Ringer

Yanıtlar:


17

Bence kimlik doğrulama ve yetkilendirmeyi karıştırıyorsunuz .

Güvenlik modelinin DB'de tutulmasının bilhassa katılıyorum, özellikle LedgerSMB, birden çok istemcinin erişimi göz önünde bulundurularak tasarlandığından. Bir ara katman katmanıyla 3 katmanlı olmayı planlamıyorsanız , özellikle bir muhasebe uygulaması gibi bir şey için kullanıcıların veritabanı rolleri olması mükemmel bir mantıklıdır.

Bu mu değil bir PostgreSQL destekli kimlik doğrulama yöntemi kullanılarak veritabanına karşı kullanıcıların kimliklerini doğrulamak zorunda anlamına gelir. Veritabanı kullanıcılarınız, rolleriniz ve bağışlarınız yalnızca isterseniz yetkilendirme için kullanılabilir .

Örneğin, bir web kullanıcı arayüzü için şu şekilde çalışır:

  • janeHTTPS X.509 istemci sertifikası anlaşması ve DIGEST yetkisi diyelim, web ui sunucusuna bağlanır ve istenen yöntemi kullanarak kimlik doğrulaması yapar. Sunucunun artık kabul ettiği bir kullanıcıdan bir bağlantısı var jane.

  • Sunucu PostgreSQL'e sabit bir kullanıcı adı / şifre (veya Kerberos ya da istediğiniz herhangi bir şey) kullanarak bağlanır ve kullanıcı olarak kendini db sunucusuna doğrular webui. Db sunucusu webuikullanıcılarını doğrulamak için güveniyor bu yüzden webuiuygun GRANTs verildi (aşağıya bakınız).

  • Bu bağlantıda sunucu SET ROLE jane;kullanıcının yetkilendirme düzeyini almak için kullanır jane. Kadar RESET ROLE;veya başka SET ROLEçalıştırılır, bağlantı ile aynı erişim haklarına sahip faaliyet janeve SELECT current_user()vb bildirir jane.

  • Sunucu sahip olduğu veritabanı bağlantısı arasındaki ilişkiyi korur SET ROLEetmek janeve kullanıcı için web oturumu jane, PostgreSQL bağlantısı yeni olmaksızın diğer kullanıcılarla diğer bağlantıları tarafından kullanılmak üzere bu izin vermeyerek SET ROLEİnbetween.

Artık sunucunun dışında kimlik doğrulaması yapıyorsunuz , ancak sunucuda yetkilendirmeyi koruyorsunuz. Pg'nin kullanıcıların neler olduğunu bilmesi gerekir, ancak onlar için şifre veya kimlik doğrulama yöntemlerine ihtiyacı yoktur.

Görmek:

ayrıntılar

Webui sunucusu çalıştırılan sorguları kontrol eder ve janeham SQL (umarım!) Çalıştırmasına izin vermeyecektir, bu yüzden web kullanıcı arayüzü üzerinden janeyapamazsınız RESET ROLE; SET ROLE special_admin_user;. Ek güvenlik için, sunucuya reddedilen SET ROLEve RESET ROLEbağlantı atanmamış veya atanmamış bağlantılar havuzuna girmedikçe bir ifade filtresi eklerdim.

Diğer istemcilerde Pg için doğrudan kimlik doğrulamayı kullanmakta hala özgürsünüz; özgürce karıştırabilir ve eşleştirebilirsiniz. Sadece zorunda kullanıcı haklarını web üzerinden giriş yapabilir ve ardından bu kullanıcılara herhangi bir normal verebilir kullanıcılara istediğiniz hakları, şifreler, vb. Kullanıcıların web okunur, olmak için onların veritabanından (ve itibaren hak ).GRANTwebuiSET ROLECONNECTREVOKECONNECTpublic

Böyle bir kimlik doğrulama / yetkilendirme bölünmesini kolaylaştırmak için her yeni kullanıcı için özel bir rolüm assume_any_uservar GRANT. Daha sonra GRANT assume_any_usergüvenilir bir web ön ucu gibi şeylerin kullandığı gerçek kullanıcı adına, onlara istedikleri herhangi bir kullanıcı olma haklarını veriyorum.

assume_any_userBir NOINHERITrol yapmak önemlidir , böylece webuikullanıcı veya kendisinin hiçbir ayrıcalığı yoktur ve veritabanına ancak SET ROLEgerçek bir kullanıcı olduğunda harekete geçebilir . Hiçbir koşulda webuibir süper kullanıcı veya DB sahibi olmamalıdır .

Bağlantı havuzu oluşturuyorsanız, SET LOCAL ROLEyalnızca bir işlem içinde rol ayarlamak için kullanabilirsiniz , böylece bağlantıyı COMMITveya sonrasında havuza geri döndürebilirsiniz ROLLBACK. RESET ROLEHala çalıştığından emin olun , böylece istemcinin istediği SQL'i çalıştırmasına izin vermek hala güvenli değildir.

SET SESSION AUTHORIZATIONbu komutun ilgili ama daha güçlü sürümüdür. Rol üyeliği gerektirmez, ancak yalnızca süper kullanıcı komutudur. Web kullanıcı arayüzünüzün bir süper kullanıcı olarak bağlanmasını istemezsiniz. Bu ile ters olabilir RESET SESSION AUTHORIZATION, SET SESSION AUTHORIZATION DEFAULTya da SET SESSION AUTHORIZATION theusernameo da bir ayrıcalık bırakarak güvenlik bariyeri olmadığı böylece süper haklarını yeniden kazanmak için.

Gibi çalıştı SET SESSION AUTHORIZATIONama geri döndürülemez ve rol üyesi olsaydınız ama süper kullanıcı olmasaydı işe yarayan bir komut harika olurdu. Bu noktada bir tane yoktur, ancak dikkatli olursanız kimlik doğrulama ve yetkilendirmeyi yine de ayırabilirsiniz.

Örnek ve açıklama

CREATE ROLE dbowner NOLOGIN;
CREATE TABLE test_table(x text);
INSERT INTO test_table(x) VALUES ('bork');
ALTER TABLE test_table OWNER TO dbowner;

CREATE ROLE assume_any_user NOINHERIT NOLOGIN;
CREATE ROLE webui LOGIN PASSWORD 'somepw' IN ROLE assume_any_user;

CREATE ROLE jane LOGIN PASSWORD 'somepw';
GRANT jane TO assume_any_user;
GRANT ALL ON TABLE test_table TO jane;

CREATE ROLE jim LOGIN PASSWORD 'somepw';
GRANT jim TO assume_any_user;

Şimdi olarak bağlan webui. Not size bir şey yapamaz o test_tableancak can SET ROLE etmek janeve daha sonra erişebileceğiniz test_table:

$ psql -h 127.0.0.1 -U webui regress
Password for user webui:

regress=> SELECT session_user, current_user;
 session_user | current_user 
--------------+--------------
 webui        | webui
(1 row)



regress=> SELECT * FROM test_table;
ERROR:  permission denied for relation test_table

regress=> SET ROLE jane;
SET

regress=> SELECT session_user, current_user;
 session_user | current_user 
--------------+--------------
 webui        | jane
(1 row)

regress=> SELECT * FROM test_table;
  x   
------
 bork
(1 row)

Not webui kutu SET ROLE için jimzaman zaten hatta,SET ROLE hiç d janeve olsa bile janeedilmemiştir GRANTrol üstlenme hakkı ed jim. SET ROLEetkin kullanıcı kimliğinizi ayarlar, ancak SET ROLEdiğer rollere olan yeteneğinizi kaldırmaz ; bu, geçerli etkin rolünüzün değil, bağlandığınız rolün bir özelliğidir. Sonuç olarak SET ROLEve RESET ROLEkomutlarına erişimi dikkatlice kontrol etmelisiniz . AFAIK, SET ROLEbir bağlantı için kalıcı olarak, kesinlikle hedef kullanıcı haline gelmenin bir yolu yoktur , ancak kesinlikle güzel olurdu.

Karşılaştırmak:

$ psql -h 127.0.0.1 -U webui regress
Password for user webui:

regress=> SET ROLE jane;
SET

regress=> SET ROLE jim;
SET
regress=> SELECT session_user, current_user;
 session_user | current_user 
--------------+--------------
 webui        | jim
(1 row)

için:

$ psql -h 127.0.0.1 -U jane regress
Password for user jane:

regress=> SET ROLE webui;
ERROR:  permission denied to set role "webui"
regress=> SET ROLE jim;
ERROR:  permission denied to set role "jim"

Bu SET ROLE, belirli bir rol olarak giriş yapmakla aynı şey değil, aklınızda bulundurmanız gereken bir şey olduğu anlamına gelir .

webui olamaz SET ROLE için dbowneryapamam GRANT:

regress=> SET ROLE dbowner;
ERROR:  permission denied to set role "dbowner"

bu yüzden kendi başına oldukça güçsüzdür, sadece diğer kullanıcıların haklarını ve sadece bu kullanıcıların web erişimi etkinleştirildiğinde kullanılabilir.


1
btw pgbouncerbazı ayrıntılar için nasıl çalıştığına bakmak isteyebilirsiniz .
Craig Ringer

2
Oh, DISCARD ALLhakların temerrüde düşmesi için başka bir yol. Ben gerçekten Pg bir SET ROLE NORESETya da benzeri olsaydı ...
Craig Ringer
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.