MongoDB menyimpan pengguna basis data beserta perannya, lalu memeriksa keduanya setiap kali sebuah koneksi meminta akses. Topik ini membahas pembuatan pengguna dengan db.createUser(), pengenalan peran bawaan (built-in roles) seperti read dan readWrite, mekanisme autentikasi SCRAM yang digunakan server untuk memverifikasi kata sandi, serta pengujian kredensial dengan db.auth(). Seluruh contoh menggunakan basis data operasional, dan dua pengguna latihan yang dibuat di awal topik dibersihkan kembali pada bagian akhir.
Pengguna basis data dan peran bawaan#
Pengguna MongoDB dibuat pada satu basis data tertentu, dan dokumen penggunanya disimpan pada basis data tersebut. Nama pengguna hanya wajib unik di dalam satu basis data, sehingga nama yang sama boleh muncul pada basis data lain dengan peran yang berbeda. Basis data tempat pengguna berada menjadi basis data autentikasi (authentication database), yaitu basis data yang disebutkan ketika kredensialnya diverifikasi. Peran menentukan tindakan yang diizinkan, misalnya membaca dokumen, menulis dokumen, atau mengelola indeks.
Jalankan mongosh, pilih basis data kerja, lalu buat dua pengguna dengan db.createUser(). Pengguna penulis menerima peran readWrite, sedangkan pembaca menerima peran read.
use operasionalswitched to db operasionaldb.createUser({
user: "penulis",
pwd: "sandiPenulis1",
roles: [ { role: "readWrite", db: "operasional" } ]
}).ok
db.createUser({
user: "pembaca",
pwd: "sandiPembaca1",
roles: [ { role: "read", db: "operasional" } ]
}).ok1
1Angka 1 pada keluaran adalah field ok dari respons perintah. Respons lengkapnya memuat stempel waktu kluster yang berubah pada setiap eksekusi, sehingga contoh pada topik ini hanya menampilkan field yang statis. Peran ditulis sebagai array dokumen, dan setiap dokumennya memasangkan nama peran dengan basis data yang menjadi sasarannya.
Tabel berikut merangkum peran bawaan yang paling sering digunakan pada tingkat basis data.
| Peran | Hak akses |
|---|---|
read | Membaca data pada seluruh koleksi basis data tersebut. |
readWrite | Membaca dan menulis data pada seluruh koleksi basis data tersebut. |
dbAdmin | Melakukan tugas administratif, misalnya mengelola indeks dan membaca statistik. |
userAdmin | Membuat dan mengubah pengguna pada basis data tersebut. |
dbOwner | Menggabungkan hak read, readWrite, dbAdmin, dan userAdmin. |
root | Mengakses seluruh sumber daya, dan hanya dapat ditetapkan pada basis data admin. |
Peran yang sudah ditetapkan diperiksa dengan db.getUser(). Keluarannya menegaskan bahwa pembaca hanya memegang satu peran baca pada basis data operasional.
db.getUser("pembaca").roles[ { role: 'read', db: 'operasional' } ]Autentikasi dengan SCRAM#
SCRAM adalah singkatan dari Salted Challenge Response Authentication Mechanism, yaitu mekanisme autentikasi bawaan MongoDB untuk memverifikasi kata sandi tanpa mengirimkannya sebagai teks polos. Server menyimpan kredensial turunan dari kata sandi, berupa hash yang dicampur dengan nilai acak bernama salt. Klien dan server kemudian saling bertukar tantangan, yaitu pertanyaan yang hanya dapat dijawab dengan benar oleh pihak yang mengetahui kata sandi tersebut. MongoDB mendukung dua versi, yaitu SCRAM-SHA-1 dan SCRAM-SHA-256, dan versi kedua menjadi bawaan sejak MongoDB 4.0. Keduanya terdaftar pada field mechanisms milik dokumen pengguna.
db.getUser("pembaca").mechanisms[ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]Kredensial yang baru dibuat diuji dengan db.auth(). Percobaan pertama sengaja menggunakan kata sandi yang salah, dan server menolaknya dengan pesan error AuthenticationFailed.
db.auth({ user: "pembaca", pwd: "sandiSalah1" })Uncaught
MongoServerError[AuthenticationFailed]: Authentication failed.Percobaan kedua menggunakan kata sandi yang benar, sehingga autentikasi berhasil dan koneksi kini teridentifikasi sebagai pembaca.
db.auth({ user: "pembaca", pwd: "sandiPembaca1" }){ ok: 1 }Penegakan autentikasi pada server#
Autentikasi yang berhasil tidak otomatis membatasi akses, karena pembatasan baru ditegakkan ketika server dijalankan dengan opsi --auth. Server latihan pada jalur ini berjalan tanpa opsi tersebut, sehingga semua operasi diizinkan untuk semua koneksi. Buktinya, penulisan dokumen dari sesi yang sudah diautentikasi sebagai pembaca tetap berhasil, padahal perannya hanya read.
db.catatan.insertOne({ topik: "uji peran", isi: "ditulis oleh pembaca" }){
acknowledged: true,
insertedId: ObjectId('6ae8a93a165c63faa28de666')
}Pada server yang menjalankan --auth, penulisan yang sama ditolak dengan error Unauthorized. Untuk menegakkan autentikasi, server dijalankan ulang dengan opsi tersebut, lalu klien menyertakan kredensialnya saat terhubung.
# tidak-dijalankan
# menjalankan ulang server dengan penegakan autentikasi
mongod --dbpath ~/mongodb-data --replSet rs0 --auth
# terhubung dengan kredensial pengguna pembaca
mongosh --authenticationDatabase operasional -u pembaca -pPerpindahan ke mode bertautentikasi sebaiknya dipersiapkan. Server yang pertama kali dijalankan dengan --auth masih mengizinkan koneksi dari localhost untuk membuat satu pengguna administratif pertama, sebuah perilaku yang disebut localhost exception. Setelah pengguna pertama ada, seluruh koneksi wajib membuktikan kredensialnya terlebih dahulu sebelum menjalankan operasi apa pun.
Kesalahan umum#
Kesalahan pertama adalah menganggap db.auth() membatasi akses pada server tanpa --auth. Mekanisme verifikasinya memang berjalan, tetapi pemeriksaan peran tidak, sehingga pengguna read tetap dapat menulis seperti pada contoh sebelumnya. Pembeda yang benar adalah opsi --auth pada proses mongod, bukan keberadaan dokumen pengguna atau hasil db.auth().
Kesalahan kedua adalah membuat pengguna pada basis data yang salah. Pengguna yang dibuat pada basis data operasional hanya dapat diautentikasi terhadap basis data tersebut. Percobaan autentikasi terhadap basis data lain berakhir dengan AuthenticationFailed karena dokumen penggunanya tidak ada di sana. Peran dan basis data autentikasi adalah dua hal yang berbeda. Peran menyatakan basis data mana yang boleh diakses, sedangkan basis data autentikasi menyimpan kredensial penggunanya.
Sesi latihan ditutup dengan menghapus kedua pengguna melalui db.dropUser(). Pada server tanpa penegakan, penghapusan tetap berhasil meskipun koneksi masih diautentikasi sebagai pembaca. Pada server dengan --auth, tugas ini dilakukan oleh pengguna yang memegang peran userAdmin atau dbOwner.
db.dropUser("pembaca").ok
db.dropUser("penulis").ok1
1Ringkasan#
- Pengguna dibuat per basis data dengan
db.createUser(), dan dokumen penggunanya tersimpan pada basis data tempat ia dibuat. - Peran bawaan seperti
read,readWrite,dbAdmin, dandbOwnermerangkum himpunan tindakan yang diizinkan. - SCRAM memverifikasi kata sandi melalui mekanisme tantangan-jawaban (challenge-response) tanpa mengirim kata sandi dalam bentuk polos.
- Pembatasan akses ditegakkan oleh opsi
--authpada server, bukan oleh keberadaan pengguna atau hasildb.auth().
Referensi#
- db.createUser — MongoDB Manual — Dokumentasi pembuatan pengguna beserta format perannya.
- Built-In Roles — MongoDB Manual — Daftar lengkap peran bawaan dan hak aksesnya.
- Authentication — MongoDB Manual — Ringkasan mekanisme autentikasi yang didukung server.
- SCRAM — MongoDB Manual — Penjelasan mekanisme SCRAM-SHA-1 dan SCRAM-SHA-256 beserta kredensial yang disimpan.
- db.auth — MongoDB Manual — Dokumentasi pengujian kredensial dari shell.
- db.dropUser — MongoDB Manual — Dokumentasi penghapusan pengguna basis data.