Semua itu JAAS

Adakah anda perlu membuat mekanisme pengesahan masuk untuk aplikasi? Kemungkinannya, anda mempunyai, dan mungkin lebih dari sekali, dengan setiap pelaksanaan baru hampir, tetapi tidak serupa dengan yang sebelumnya. Sebagai contoh, satu pelaksanaan mungkin menggunakan pangkalan data Oracle, yang lain mungkin menggunakan pengesahan NT, dan yang lain, direktori LDAP (protokol direktori akses ringan). Bukankah lebih baik untuk menyokong semua mekanisme keselamatan ini tanpa mengubah kod peringkat aplikasi?

Sekarang di dunia Java, Anda dapat menggunakan Java Authentication and Authorization Service (JAAS). API yang agak baru ini merupakan peluasan dalam J2SE (Java 2 Platform, Standard Edition) 1.3, merupakan inti API di J2SE 1.4, dan juga merupakan bagian dari spesifikasi J2EE (Java 2 Platform, Enterprise Edition) 1.3. Dalam artikel ini, kami akan mengajar anda keperluan JAAS dan menunjukkan kepada anda cara menerapkan JAAS secara berkesan pada aplikasi dunia nyata. Kami mendasarkan aplikasi artikel ini berdasarkan pengalaman kami sendiri mengintegrasikan JAAS ke dalam sistem Java Web yang ada yang menggunakan RDBMS (sistem pengurusan pangkalan data relasional) untuk menyimpan maklumat login pengguna. Dengan JAAS, kami merancang mekanisme log masuk dan pengesahan yang lebih mantap, fleksibel, dan konsisten.

Anda boleh memuat turun sekumpulan contoh kerja lengkap dari Sumber di bawah (termasuk sumber Java, JSP (JavaServer Pages), konfigurasi JAAS, dengan pangkalan data dan skrip binaan). Kami menguji contoh-contoh ini menggunakan pelayan Resin dengan JDBC (Java Database Connectivity) dan pangkalan data MySQL.

Pengesahan dan Pengesahan Java: Gambaran besar

Sebelum JAAS, model keamanan Java sebagian besar dibentuk oleh asalnya sebagai bahasa yang tidak bergantung pada platform untuk aplikasi yang diedarkan dan di jaringan. Pada masa awalnya, Java sering muncul sebagai kod mudah alih, seperti applet berasaskan penyemak imbas, dan oleh itu, model keselamatan awal difokuskan pada melindungi pengguna berdasarkan dari mana kod itu berasal dan siapa yang membuatnya. Mekanisme keselamatan Java awal seperti SecurityManagers, konsep kotak pasir, penandatanganan kod, dan file kebijakan semuanya bertujuan untuk melindungi pengguna dari sistem.

Penemuan JAAS mencerminkan evolusi Java menjadi bahasa pengaturcaraan tujuan umum, yang digunakan untuk melaksanakan aplikasi pelanggan dan pelayan tradisional yang memerlukan kawalan masuk dan akses. JAAS melindungi sistem daripada pengguna dengan membenarkan atau menolak akses berdasarkan siapa atau apa yang menjalankan program. Walaupun JAAS dapat melakukan pengesahan dan pengesahan, dalam artikel ini, kami lebih mengutamakan pengesahan.

JAAS dapat mempermudah pengembangan keselamatan Java anda dengan meletakkan lapisan abstraksi antara aplikasi anda dan mekanisme pengesahan dan kebenaran yang berbeza. Kebebasan dari platform dan algoritma ini membolehkan anda menggunakan mekanisme keselamatan yang berbeza tanpa mengubah kod tahap aplikasi anda. Seperti kebanyakan API keselamatan Java, JAAS mencapai kebebasan pelaksanaan ini melalui kerangka antara muka penyedia perkhidmatan (SPI) yang dapat diperluas: sekumpulan kelas dan antara muka abstrak yang mana implementasi khusus dikembangkan.

Gambar 1 di bawah memberikan gambaran umum tahap tinggi bagaimana JAAS mencapai kebolehpasaran ini. Kod lapisan aplikasi anda terutama berkaitan dengan a LoginContext. Di bawahnya LoginContextadalah satu set dari satu atau beberapa LoginModules yang dikonfigurasi secara dinamik , yang menangani pengesahan sebenar menggunakan infrastruktur keselamatan yang sesuai.

JAAS menyediakan beberapa LoginModulepelaksanaan rujukan , seperti JndiLoginModule; anda juga boleh mengembangkan sendiri, seperti yang akan kita lakukan di sini dengan RdbmsLoginModule. Kami juga akan menunjukkan bagaimana anda dapat mengatur aplikasi dengan cepat dengan pilihan implementasi menggunakan file konfigurasi sederhana.

Selain dapat dipasang, JAAS dapat disusun: dalam konteks satu log masuk, satu set modul keselamatan dapat saling tumpang tindih, masing-masing dipanggil secara teratur dan masing-masing berinteraksi dengan infrastruktur keselamatan yang berbeza.

Aspek JAAS dimodelkan pada beberapa corak seni bina keselamatan dan kerangka kerja yang ada. Ciri stackable, misalnya, sengaja menyerupai rangka kerja Unix Pluggable Authentication Module (PAM). Dari sudut pandang transaksional, JAAS menggunakan tingkah laku yang serupa dengan protokol komit dua fasa (2PC). Konsep konfigurasi keselamatan JAAS, termasuk Policyfail dan Permissions, berasal dari pakej keselamatan J2SE 1.2. JAAS juga meminjam idea dari kerangka keselamatan lain yang mapan, seperti sijil X.509, dari mana nama Subjectitu berasal (anda akan mengetahui lebih lanjut Subjectkemudian).

Catatan: JAAS hanyalah salah satu daripada beberapa API keselamatan Java baru. Untuk maklumat lanjut mengenai keselamatan Java, lihat bar sisi "Teka-teki Keselamatan Java" dan Sumber di bawah.

JAAS sisi pelanggan dan pelayan

Anda boleh menggunakan JAAS pada kedua-dua pelanggan dan pelayan. Menggunakannya di sisi pelanggan adalah mudah, seperti yang akan kami tunjukkan sebentar lagi. Dari segi pelayan, perkara menjadi lebih rumit. Pada masa ini, JAAS di pasaran pelayan aplikasi agak tidak konsisten; Pelayan aplikasi J2EE menggunakan JAAS sedikit berbeza, bergantung pada mana yang anda gunakan. Sebagai contoh, JBossSX, menggunakan seni bina mereka sendiri, menggabungkan JAAS dengan baik ke dalam kerangka keselamatan keseluruhannya (yang diperincikan dalam artikel JavaWorld Scott Stark yang sangat baik "Mengintegrasikan Infrastruktur Keselamatan dengan JBossSX" (Ogos 2001)). Walau bagaimanapun, walaupun WebLogic 6.x menyokong JAAS, butirannya berbeza.

Oleh itu, anda dapat memahami JAAS dari perspektif pelayan dan pelanggan, kami akan menunjukkan contoh kedua-duanya dalam artikel ini. Dan untuk tujuan kesederhanaan pada pelayan, kami akan menggunakan pelayan aplikasi Resin supaya kami dapat memulakannya dengan batu tulis yang lebih bersih (Resin memang mempunyai skema pengesahan yang dapat dipasang sendiri, tetapi tidak standard, jadi menggunakan JAAS memberi kami lebih banyak kemudahan pilihan kemudian).

Teras JAAS

Untuk memulakan dengan JAAS, anda mesti memastikannya dipasang. J2SE 1.4 sudah merangkumi JAAS; J2SE 1.3 tidak. Sekiranya anda ingin terus menggunakan J2SE 1.3, muat turun JAAS dari Sun Microsystems. Sebaik sahaja anda memuat turun dan memasang JAAS ke direktori tertentu, anda akan melihat subdirektori yang dipanggil lib, yang mengandungi satu fail bernama jaas.jar. Anda perlu menambahkan fail ini ke classpath anda atau menyalinnya ke direktori sambungan JRE (Java Runtime Environment) anda (di \lib\extmana lokasi JRE anda). Anda kemudian bersedia untuk JAAS. Catatan: Sekiranya anda menggunakan pelayan aplikasi, mungkin sudah termasuk JAAS. Periksa dokumentasi pelayan anda untuk perincian.

Dengan pendekatan ini, perhatikan bahawa anda dapat mengubah beberapa tetapan harta tanah sistem yang berkaitan dengan JAAS (serta banyak tetapan keselamatan Java yang lain) dalam fail sifat keselamatan Java. Fail ini, java.securityterletak di /lib/securitydirektori dan ditulis dalam format fail sifat Java standard.

Menggunakan pengesahan JAAS dari aplikasi anda biasanya melibatkan langkah-langkah berikut:

  1. Buat a LoginContext
  2. Secara pilihan, hantar a CallbackHandlerke LoginContext, untuk mengumpulkan atau memproses data pengesahan
  3. Melaksanakan pengesahan dengan menghubungi LoginContext's login()kaedah
  4. Lakukan tindakan istimewa menggunakan yang dikembalikan Subject(dengan andaian berjaya)

Inilah contoh minimum:

LoginContext lc = LoginContext baru ("MyExample"); cuba {lc.login (); } tangkapan (LoginException) {// Pengesahan gagal. } // Pengesahan berjaya, kini kami dapat meneruskannya. // Kita boleh menggunakan Subjek yang dikembalikan jika kita mahu. Subjek subjek = lc.getSubject (); Subject.doAs (sub, MyPrivilegedAction baru ());

Di bawah penutup, beberapa perkara lain berlaku:

  1. Semasa inisialisasi, LoginContextmencari entri konfigurasi "MyExample"dalam fail konfigurasi JAAS (yang anda konfigurasikan) untuk menentukan LoginModules mana yang akan dimuat (lihat Gambar 2)
  2. Semasa log masuk, yang LoginContextmemanggil setiap LoginModule's login()kaedah
  3. Setiap login()kaedah melakukan pengesahan atau memasukkan aCallbackHandler
  4. The CallbackHandlerkegunaan satu atau lebih Callbacks untuk berinteraksi dengan pengguna dan mengumpul input
  5. A new Subject instance is populated with authentication details such as Principals and credentials

We'll explain further details below, but to begin, let's look at the key JAAS classes and interfaces involved in the process. These are typically divided into the following three groups:

Table 1. JAAS classes and interfaces

Common Subject, Principal, credential (credential is not any specific class, but can be any object)
Authentication LoginContext, LoginModule, CallbackHandler, Callback
Authorization Policy, AuthPermission, PrivateCredentialPermission

Most of these classes and interfaces are in the javax.security.auth package's subpackages, with some prebuilt implementations in the com.sun.security.auth package, included only in J2SE 1.4.

Note: Because we focus on authentication in this article, we don't delve into the authorization classes.

Common: Subjects, Principals, and Credentials

The Subject class represents an authenticated entity: an end-user or administrator, or a Web service, device, or another process. The class contains three sets of security information types:

  • Identities: In the form of one or more Principals
  • Public credentials: Such as name or public keys
  • Private credentials: Like passwords or private keys

Principals represent Subject identities. They implement the java.security.Principal interface (which predates JAAS) and java.io.Serializable. A Subject's most important method is getName(), which returns an identity's string name. Since a Subject instance contains an array of Principals, it can thus have multiple names. Because a social security number, login ID, email address, and so on, can all represent one user, multiple identities prove common in the real world.

The last element here, credential, is not a class or an interface, but can be any object. Credentials can include any authentication artifact, such as a ticket, key, or password, that specific security systems might require. The Subject class maintains unique Sets of private and public credentials, which can be retrieved with methods such as getPrivateCredentials() and getPublicCrendentials(). These methods are more often used by security subsystems than at the application layer.

Authentication: LoginContext

Your application layer uses LoginContext as its primary class for authenticating Subjects. LoginContext also represents where JAAS's dynamic pluggability comes into play, because when you construct a LoginContext, you specify a named configuration to load. The LoginContext typically loads the configuration information from a text file, which in turn tells the LoginContext which LoginModules to use during login.

The three commonly used methods in LoginContext are:

Table 2. LoginContext methods

login() Performs login, a relatively complex step that invokes all LoginModules specified for this configuration. If it succeeds, it creates an authenticated Subject. If it fails, it throws a LoginException.
getSubject() Returns the authenticated Subject.
logout() Logs out the authenticated Subject and removes its Principals and credentials.

We will show how to use these methods later.

Authentication: LoginModule

LoginModule is the interface to specific authentication mechanisms. J2SE 1.4 ships with a set of ready-to-use LoginModules, including:

Table 3. LoginModules in J2SE 1.4

JndiLoginModule Verifies against a directory service configured under JNDI (Java Naming and Directory Interface)
Krb5LoginModule Authenticates using Kerberos protocols
NTLoginModule Uses the current user's NT security information to authenticate
UnixLoginModule Uses the current user's Unix security information to authenticate

Along with these modules comes a set of corresponding concrete Principal implementations in the com.sun.security.auth package, such as NTDomainPrincipal and UnixPrincipal.

The LoginModule interface has five methods:

Table 4. LoginModule methods

initialize() Called after the LoginModule is constructed.
login() Performs the authentication.
commit() Called by the LoginContext after it has accepted the results from all LoginModules defined for this application. We assign Principals and credentials to the Subject here.
abort() Called when any LoginModule for this application fails (even though earlier ones in sequence may have succeeded—thus akin to a 2PC model). No Principals or credentials are assigned to the Subject.
logout() Removes the Principals and credentials associated with the Subject.

The application layer calls none of these methods directly—the LoginContext invokes them as needed. Our example below will elaborate on these methods' implementations.

Authentication: CallbackHandlers and Callbacks

CallbackHandlers dan Callbacks membiarkan LoginModulepengumpulan maklumat pengesahan yang diperlukan dari pengguna atau sistem, sementara tetap bebas dari mekanisme interaksi yang sebenarnya. Kami akan memanfaatkan kemampuan itu dalam reka bentuk kami — kami RdbmsLoginModuletidak bergantung pada bagaimana kelayakan pengguna (nama pengguna / kata laluan) diperoleh dan dengan itu dapat digunakan dalam lingkungan aplikasi yang akan kami gambarkan (baik dari baris perintah atau dari JSP) .