Keamanan J2EE: Kontainer versus kustom

Sejak pertama kali halaman login ditambahkan ke aplikasi Web, keamanan selalu menjadi salah satu komponen kunci yang penting bagi keberhasilan aplikasi di Web. Secara historis, semuanya diberi kode dengan tangan. Setiap aplikasi Web memiliki metode khusus untuk mengautentikasi dan kemudian memberi otorisasi kepada pengguna. Pengembang juga membangun komponen untuk pendaftaran, administrasi, dan fungsi lain yang diperlukan. Meskipun membutuhkan banyak biaya, pendekatan ini memungkinkan fleksibilitas yang tinggi.

Dengan munculnya JAAS, Layanan Otentikasi dan Otorisasi Java, aplikasi memperoleh serangkaian antarmuka dan konfigurasi yang dapat mereka manfaatkan untuk menstandarkan tugas-tugas tersebut. Bahkan dengan penambahan JAAS ke spesifikasi, J2EE masih memiliki beberapa masalah yang harus diselesaikan sebelum pengembang aplikasi dapat berhenti membuat API khusus. Memilih antara menggunakan standar J2EE atau membuat solusi kustom memerlukan pengetahuan trade-off dari masing-masing dan, tentu saja, persyaratan aplikasi Anda.

Artikel ini bertujuan untuk memberikan semua informasi yang diperlukan untuk memutuskan antara keamanan khusus atau kontainer. Saya membahas fungsi keamanan aplikasi yang paling umum untuk memberikan latar belakang keamanan yang diperlukan. Berikut pembahasannya adalah penjelasan rinci tentang implementasi keamanan J2EE yang disediakan oleh spesifikasi serta metode paling umum untuk menerapkan keamanan kustom. Setelah Anda lebih memahami setiap metode, Anda harus memiliki informasi yang cukup untuk memilih metode mana yang paling sesuai dengan persyaratan aplikasi Anda.

Apa itu wadah?

Sebelum kita membahas berbagai jenis keamanan dan masalah implementasi keamanan, mari kita tinjau apa itu wadahadalah. Kontainer adalah lingkungan tempat aplikasi berjalan. Ini juga identik dengan server aplikasi J2EE. Dalam hal wadah J2EE, aplikasi J2EE berjalan di dalam wadah, yang memiliki tanggung jawab khusus sehubungan dengan aplikasi tersebut. Ada berbagai jenis wadah J2EE dan berbagai tingkat dukungan J2EE. Tomcat dari Apache adalah wadah Web yang hanya mengimplementasikan bagian Servlet (aplikasi Web) dari spesifikasi J2EE. WebLogic BEA adalah server aplikasi J2EE yang sepenuhnya patuh, artinya mendukung semua aspek spesifikasi J2EE dan telah lulus tes sertifikasi J2EE dari Sun. Jika Anda tidak yakin dengan dukungan yang diberikan server aplikasi Anda, hubungi vendor untuk informasi lebih lanjut.

Keamanan aplikasi

Topik lain yang harus kita bahas sebelum kita mulai adalah perbedaan antara keamanan aplikasi dan jenis keamanan lainnya. Keamanan aplikasi adalah keamanan yang dilakukan secara langsung oleh aplikasi atau tidak langsung oleh kerangka kerja atau wadah untuk aplikasi yang berkaitan dengan pengguna aplikasi tersebut. Contoh pengguna aplikasi adalah seseorang yang masuk ke toko buku online dan membeli beberapa buku Java. Jenis keamanan lain yang ada, seperti keamanan jaringan dan keamanan JVM. Salah satu contoh dari tipe keamanan tersebut adalah pengguna yang memulai proses Java di mesin. Sepanjang sisa makalah ini, setiap kali saya membahas keamanan, yang saya maksud adalah keamanan aplikasi. Jenis keamanan lain menjangkau di luar cakupan diskusi ini.

Fokus di sini secara khusus adalah keamanan J2EE, yang merupakan jenis keamanan aplikasi karena berhubungan dengan pengguna aplikasi J2EE (yaitu, pemanggil). Pengguna bisa jadi seseorang yang menggunakan toko buku online atau aplikasi lain yang menggunakan layanan pembelian aplikasi toko buku tersebut, seperti pengecer online lainnya.

Fungsi keamanan aplikasi

Ada lima fungsi utama saat mempertimbangkan keamanan aplikasi: otentikasi, otorisasi, pendaftaran, pemeliharaan akun (pembaruan), dan penghapusan / inaktivasi akun. Meskipun hanya sebagian kecil dari semua kemungkinan fungsi yang mungkin dimiliki aplikasi, ini adalah yang paling mendasar dan cukup standar untuk semua aplikasi. Secara kurang formal, fungsi-fungsi ini adalah mengetahui pengguna (otentikasi), mengetahui apa yang dapat dilakukan pengguna (otorisasi), membuat pengguna baru (pendaftaran), memperbarui informasi pengguna (pemeliharaan akun), dan menghapus pengguna atau mencegah pengguna mengakses aplikasi. (penghapusan akun).

Sebagian besar aplikasi memungkinkan pengguna atau administrator untuk menjalankan fungsi ini. Saat pengguna menjalankan fungsi ini, mereka melakukannya sendiri. Administrator selalu menjalankan fungsi ini atas nama pengguna lain.

Seperti yang akan diilustrasikan, semua fungsi ini tidak dapat dilakukan tanpa solusi khusus, bahkan untuk otentikasi. Kami akan membahas masing-masing secara singkat untuk mengilustrasikan lebih lanjut konsep dan apa kekurangan J2EE yang harus dibuat khusus.

Autentikasi

Otentikasi adalah proses mengidentifikasi pengguna yang berinteraksi dengan aplikasi. Pada saat penulisan ini, otentikasi J2EE dapat diimplementasikan menggunakan berbagai solusi, masing-masing ditetapkan sebagai bagian dari spesifikasi J2EE (versi 1.0-1.4). Otentikasi adalah konsep utama dari diskusi ini dan akan dibahas lebih detail nanti. Penting untuk disadari bahwa otentikasi adalah fungsi keamanan yang memiliki dukungan paling besar dalam spesifikasi J2EE, tetapi kode atau konfigurasi khusus biasanya diperlukan untuk menerapkan otentikasi J2EE (alias otentikasi kontainer).

Otorisasi

Otorisasi adalah proses memverifikasi bahwa pengguna memiliki izin untuk melakukan tindakan tertentu. J2EE mencakup topik ini, tetapi dibatasi pada otorisasi berbasis peran, yang berarti bahwa aktivitas dapat dibatasi berdasarkan peran yang telah diberikan oleh pengguna. Misalnya, pengguna dengan peran manajer mungkin dapat menghapus inventaris, sementara pengguna dengan peran karyawan mungkin tidak dapat.

Selain itu, aplikasi mungkin mempertimbangkan dua jenis otorisasi: Java Runtime Environment (JRE) / container dan otorisasi aplikasi. Otorisasi JRE / container adalah proses untuk menentukan apakah pengguna yang membuat permintaan memiliki hak untuk melakukannya. JRE / container menentukan ini sebelum kode apa pun dieksekusi. Contohnya adalah wadah J2EE yang harus terlebih dahulu memeriksa apakah pengguna saat ini memiliki izin untuk menjalankan servlet (melalui batasan URL sumber daya) sebelum menjalankan servlet. Jenis otorisasi ini juga dikenal sebagai keamanan deklaratifkarena dideklarasikan dalam file konfigurasi untuk aplikasi Web. Kecuali didukung oleh penampung, keamanan deklaratif tidak dapat diubah saat runtime. Keamanan deklaratif dapat digunakan dalam banyak cara untuk memberi otorisasi kepada pengguna aplikasi J2EE, tetapi topik tersebut berada di luar cakupan diskusi ini. (Lihat Servlet 2.3 Spesifikasi Bab 12. Bagian 2 mencakup keamanan deklaratif, dan 8 adalah titik awal yang baik untuk batasan keamanan.)

Seperti disebutkan sebelumnya, pengguna mungkin aplikasi lain atau hanya pengguna aplikasi. Apa pun itu, JRE / otorisasi penampung dilakukan selama setiap permintaan. Permintaan ini mungkin permintaan HTTP dari browser ke aplikasi Web atau panggilan EJB (Enterprise JavaBeans) jarak jauh. Dalam kedua kasus, asalkan JRE / penampung mengetahui pengguna, itu dapat melakukan otorisasi berdasarkan informasi pengguna tersebut.

Otorisasi aplikasi adalah proses otorisasi saat aplikasi dijalankan. Otorisasi aplikasi selanjutnya dapat dipecah menjadi otorisasi berbasis peran dan berbasis segmen. Contoh otorisasi aplikasi berbasis peran adalah ketika aplikasi menerapkan tingkat markup yang berbeda berdasarkan apakah pengguna adalah karyawan atau pengunjung (yaitu, diskon karyawan). J2EE menyediakan API yang disebut keamanan program untuk menyelesaikan otorisasi berbasis peran (lihat Servlet 2.3 Spesifikasi Bab 12, Bagian 3 untuk informasi lebih lanjut).

Otorisasi berbasis segmen adalah otorisasi berdasarkan atribut lain milik pengguna, seperti usia atau hobi. Otorisasi berbasis segmen disebut demikian karena mengelompokkan pengguna ke dalam segmen berdasarkan atribut tertentu. J2EE tidak memiliki metode penerapan otorisasi berbasis segmen. Contoh otorisasi berbasis segmen adalah apakah tombol pada formulir dapat dilihat oleh pengguna berusia di atas 40 tahun. Vendor tertentu mungkin menawarkan jenis otorisasi ini, tetapi ini akan menjamin vendor terkunci dalam semua kasus.

Registrasi

Pendaftaran adalah proses menambahkan pengguna baru ke aplikasi. Pengguna aplikasi mungkin dapat membuat akun baru untuk dirinya sendiri atau aplikasi mungkin memilih untuk membatasi aktivitas ini untuk administrator aplikasi. Spesifikasi J2EE tidak memiliki API atau konfigurasi yang memungkinkan aplikasi menambahkan pengguna baru; oleh karena itu, jenis keamanan ini selalu dibuat secara khusus. J2EE tidak memiliki kemampuan untuk memberi tahu wadah bahwa pengguna baru telah terdaftar dan informasinya harus dipertahankan dan dipertahankan selama sesinya.

Pemeliharaan

Pemeliharaan akun adalah proses mengubah informasi akun, seperti informasi kontak, login, atau kata sandi. Sebagian besar aplikasi memungkinkan pengguna aplikasi, serta administrator, untuk melakukan pemeliharaan. Spesifikasi J2EE juga tidak memiliki API atau konfigurasi untuk pemeliharaan akun. Mekanisme tidak ada untuk memberi tahu penampung bahwa informasi pengguna telah berubah.

Penghapusan

Penghapusan akun biasanya dibatasi hanya untuk pengguna administratif. Terkadang, beberapa aplikasi memungkinkan pengguna untuk menghapus akun mereka sendiri. Sebagian besar aplikasi sebenarnya tidak pernah menghapus pengguna; mereka hanya menonaktifkan akun sehingga pengguna tidak dapat lagi masuk. Melakukan penghapusan yang keras dan cepat biasanya tidak disukai karena data akun jauh lebih sulit untuk dihidupkan kembali jika perlu. J2EE tidak memberikan cara untuk menghapus atau menonaktifkan pengguna dari aplikasi. Ini tidak memiliki mekanisme untuk memberi tahu penampung bahwa pengguna tertentu telah dinonaktifkan atau dihapus. J2EE juga tidak memiliki mekanisme untuk segera mengeluarkan pengguna dari aplikasi ketika akunnya telah dihapus.

Apa itu otentikasi kontainer?

Otentikasi kontainer adalah proses memberi tahu kontainer identitas pengguna yang membuat permintaan saat ini. Untuk sebagian besar penampung, proses ini melibatkan pengaitan ServletRequestobjek saat ini , utas eksekusi saat ini, dan sesi internal dengan identitas pengguna. Dengan mengaitkan sesi dengan identitas, penampung dapat menjamin bahwa permintaan saat ini dan semua permintaan berikutnya oleh pengguna yang sama dapat dikaitkan dengan sesi yang sama, hingga sesi pengguna tersebut berakhir. Objek sesi ini biasanya tidak sama dengan HttpSessionobjek, meskipun objek sesi digunakan untuk membuat dan mempertahankan objek sesi terakhir. Setiap permintaan berikutnya oleh pengguna yang sama dikaitkan dengan sesi menggunakan penulisan ulang URL atau cookie sesi, sesuai dengan Spesifikasi Servlet 2.3, Bab 7.

Seperti yang disebutkan di atas dalam diskusi kita tentang otorisasi, setiap tindakan yang dilakukan container serta setiap tindakan yang dilakukan JRE atas nama pengguna tersebut diperiksa dengan cermat untuk memastikan pengguna memiliki izin untuk menjalankan tindakan tersebut. Untuk mengulangi contoh kami sebelumnya, ketika kontainer mengeksekusi servlet atas nama pengguna, itu memverifikasi bahwa pengguna termasuk dalam set peran yang diberikan izin untuk mengeksekusi servlet itu. JRE 1.4 juga melakukan pemeriksaan ini untuk banyak tindakan, termasuk ketika file atau soket terbuka. Otentikasi JRE adalah konsep yang kuat dan dapat memastikan bahwa setiap permintaan ke wadah pada dasarnya aman.

Saat ini, J2EE menyediakan beberapa mekanisme berbeda untuk mengimplementasikan otentikasi pengguna. Ini termasuk otentikasi berbasis formulir, otentikasi klien HTTPS, dan otentikasi dasar HTTP. JAAS disertakan sebagai metode otentikasi wajib yang harus didukung oleh kontainer. Namun spesifikasinya tidak ketat tentang bagaimana wadah harus menyediakan fungsionalitas ini; Oleh karena itu, setiap wadah memberikan dukungan yang berbeda untuk JAAS. Selain itu, JAAS dengan sendirinya merupakan kerangka kerja otentikasi mandiri dan dapat digunakan untuk mengimplementasikan otentikasi kontainer terlepas dari apakah spesifikasi mendukungnya. Saya akan menjelaskan konsep ini lebih detail nanti.

Setiap mekanisme otentikasi menyediakan cara standar untuk memberikan informasi wadah tentang pengguna. Saya menyebut ini sebagai realisasi kredensial . Penampung masih harus menggunakan informasi ini untuk memverifikasi bahwa pengguna ada dan memiliki izin yang memadai untuk membuat permintaan. Saya menyebutnya sebagai otentikasi kredensial . Beberapa penampung menyediakan konfigurasi untuk menyiapkan autentikasi kredensial dan penampung lainnya menyediakan antarmuka yang harus diterapkan.

Metode otentikasi J2EE

Mari kita lihat secara singkat beberapa metode paling umum untuk mengimplementasikan dan mengonfigurasi otentikasi container.

Otentikasi berbasis formulir

Otentikasi berbasis formulir memungkinkan pengguna untuk diidentifikasi dan diautentikasi dengan server aplikasi J2EE menggunakan bentuk HTML apa pun. Tindakan formulir harus j_security_checkdan dua parameter permintaan HTTP (bidang masukan formulir) harus selalu ada dalam permintaan, yang satu dipanggil j_usernamedan yang lainnya j_password,. Menggunakan otentikasi berbasis formulir, realisasi kredensial terjadi saat formulir dikirimkan dan nama pengguna dan kata sandi dikirim ke server.

Berikut adalah contoh halaman JSP (JavaServer Pages) yang menggunakan otentikasi berbasis formulir:

 Login Masukkan nama pengguna Anda:

Masukkan kata sandi Anda: