Saya pikir Anda sedang mengkonfigurasi otentikasi dan otorisasi .
Saya sepenuhnya setuju bahwa menjaga model keamanan dalam DB adalah bijaksana, terutama karena LedgerSMB dirancang dengan akses dari banyak klien. Kecuali Anda berencana untuk pergi 3-tier dengan lapisan middleware itu membuat sempurna akal untuk memiliki pengguna sebagai peran database, terutama untuk sesuatu seperti sebuah aplikasi akuntansi.
Ini tidak berarti Anda harus mengautentikasi pengguna terhadap database menggunakan metode otentikasi yang didukung PostgreSQL. Pengguna, peran, dan hibah basis data Anda hanya dapat digunakan untuk otorisasi jika Anda mau.
Inilah cara kerjanya untuk web ui misalnya:
jane
terhubung ke server web ui dan diautentikasi menggunakan metode apa pun yang diinginkan, katakanlah HTTPS X.509 sertifikat tangan klien dan DIGEST auth. Server sekarang memiliki koneksi dari pengguna yang diterimanya benar-benar jane
.
Server terhubung ke PostgreSQL menggunakan nama pengguna / kata sandi tetap (atau Kerberos atau apa pun yang Anda suka), mengautentikasi diri ke server db sebagai pengguna webui
. Server db percaya webui
untuk mengotentikasi penggunanya sehingga webui
telah diberikan yang sesuai GRANT
(lihat di bawah).
Pada koneksi yang digunakan server SET ROLE jane;
untuk mengasumsikan tingkat otorisasi pengguna jane
. Sampai RESET ROLE;
atau yang lain SET ROLE
dijalankan, koneksi beroperasi dengan hak akses yang sama seperti jane
dan SELECT current_user()
dll akan melaporkan jane
.
Server mempertahankan hubungan antara koneksi database yang memiliki SET ROLE
ke jane
dan sesi web untuk pengguna jane
, tidak memungkinkan koneksi PostgreSQL untuk digunakan oleh koneksi lain dengan pengguna lain tanpa baru SET ROLE
peralihan.
Anda sekarang mengautentikasi di luar server, tetapi mempertahankan otorisasi di server. Pg perlu tahu apa yang ada pengguna, tetapi tidak perlu kata sandi atau metode otentikasi untuk mereka.
Lihat:
Detail
Server webui mengontrol menjalankan kueri, dan itu tidak akan membiarkan jane
menjalankan SQL mentah (saya harap!) Jadi jane
tidak bisa RESET ROLE; SET ROLE special_admin_user;
melalui web ui. Untuk keamanan tambahan, saya akan menambahkan filter pernyataan ke server yang menolak SET ROLE
dan RESET ROLE
kecuali jika koneksi itu masuk atau memasuki kumpulan koneksi yang belum ditetapkan.
Anda masih bebas menggunakan otentikasi langsung ke Pg di klien lain; Anda dapat mencampur dan mencocokkan secara bebas. Anda hanya perlu GRANT
satu webui
pengguna hak untuk SET ROLE
untuk pengguna yang dapat log in melalui web dan kemudian memberikan para pengguna setiap yang normal CONNECT
hak, password, dll yang Anda inginkan. Jika Anda ingin membuatnya hanya web, hak REVOKE
mereka CONNECT
pada database (dan dari public
).
Untuk mempermudah pemisahan otentikasi / otorisasi, saya memiliki peran khusus assume_any_user
yang harus saya GRANT
gunakan untuk setiap pengguna yang baru dibuat. Saya kemudian GRANT assume_any_user
menggunakan nama pengguna asli yang digunakan oleh hal-hal seperti front-end web tepercaya, memberi mereka hak untuk menjadi pengguna yang mereka sukai.
Sangat penting untuk membuat assume_any_user
sebuah NOINHERIT
peran, sehingga webui
pengguna atau apa pun tidak memiliki privilges dengan diri dan hanya dapat bertindak pada database setelah itu SET ROLE
untuk pengguna nyata. Dalam kondisi apa pun, webui
pemilik superuser atau DB tidak boleh .
Jika Anda koneksi pooling, Anda dapat menggunakan SET LOCAL ROLE
untuk mengatur peran hanya dalam transaksi, sehingga Anda dapat mengembalikan koneksi ke pool setelah COMMIT
atau ROLLBACK
. Waspadai itu RESET ROLE
masih berfungsi, jadi masih tidak aman untuk membiarkan klien menjalankan SQL apa pun yang mereka inginkan.
SET SESSION AUTHORIZATION
adalah versi terkait tetapi lebih kuat dari perintah ini. Itu tidak memerlukan peran peran, tapi itu perintah superuser saja. Anda tidak ingin ui web Anda terhubung sebagai superuser. Itu bisa dibalik dengan RESET SESSION AUTHORIZATION
, SET SESSION AUTHORIZATION DEFAULT
atau SET SESSION AUTHORIZATION theusername
untuk mendapatkan kembali hak pengguna super sehingga bukan penghalang keamanan yang menjatuhkan hak istimewa juga.
Perintah yang berfungsi seperti SET SESSION AUTHORIZATION
tetapi tidak dapat dipulihkan dan akan bekerja jika Anda adalah anggota peran tetapi bukan superuser akan bagus. Pada titik ini tidak ada satu, tetapi Anda masih dapat memisahkan otentikasi dan otorisasi dengan cukup baik jika Anda berhati-hati.
Contoh dan penjelasan
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;
Sekarang terhubung sebagai webui
. Perhatikan bahwa Anda tidak dapat melakukan apapun untuk test_table
tetapi Anda bisa SET ROLE
untuk jane
dan kemudian Anda dapat mengakses 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)
Perhatikan itu webui
bisa SET ROLE
to jim
, bahkan ketika sudah SET ROLE
d to jane
dan meskipun jane
belum memiliki GRANT
hak untuk mengambil peran jim
. SET ROLE
menetapkan ID pengguna efektif Anda, tetapi itu tidak menghapus kemampuan Anda untuk SET ROLE
peran lain, itu adalah properti dari peran yang Anda hubungkan, bukan peran efektif Anda saat ini. Akibatnya Anda harus hati-hati mengontrol akses ke SET ROLE
dan RESET ROLE
perintah. Ada, AFAIK, tidak ada cara untuk secara permanen SET ROLE
untuk koneksi, benar-benar menjadi pengguna target, meskipun tentu akan menyenangkan untuk dimiliki.
Membandingkan:
$ 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)
untuk:
$ 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"
Ini berarti bahwa SET ROLE
tidak persis sama dengan masuk sebagai peran yang diberikan, sesuatu yang harus Anda ingat.
webui
tidak bisa SET ROLE
untuk dbowner
karena belum GRANT
ed yang tepat:
regress=> SET ROLE dbowner;
ERROR: permission denied to set role "dbowner"
jadi dengan sendirinya itu tidak berdaya, itu hanya dapat mengasumsikan hak-hak pengguna lain dan hanya ketika para pengguna memiliki akses web diaktifkan.