JavaRush /Java Blog /Random-ID /JAAS - Pengantar Teknologi (Bagian 1)
Viacheslav
Level 3

JAAS - Pengantar Teknologi (Bagian 1)

Dipublikasikan di grup Random-ID
Keamanan akses telah diterapkan di Java sejak lama dan arsitektur untuk menyediakan keamanan ini disebut JAAS - Layanan Otentikasi dan Otorisasi Java. Ulasan ini akan mencoba mengungkap misteri apa itu otentikasi, otorisasi, dan apa hubungannya JAAS dengannya. Bagaimana JAAS berteman dengan Servlet API, dan di mana mereka memiliki masalah dalam hubungan mereka.
JAAS - Pengantar Teknologi (Bagian 1) - 1

Perkenalan

Dalam ulasan ini saya ingin membahas topik seperti keamanan aplikasi web. Java memiliki beberapa teknologi yang memberikan keamanan: Namun pembicaraan kita hari ini adalah tentang teknologi lain, yang disebut “Layanan Otentikasi dan Otorisasi Java (JAAS)”. Dialah yang menjelaskan hal-hal penting seperti otentikasi dan otorisasi. Mari kita lihat ini lebih terinci.
JAAS - Pengantar Teknologi (Bagian 1) - 2

JAAS

JAAS adalah perpanjangan dari Java SE dan dijelaskan dalam Panduan Referensi Layanan Otentikasi dan Otorisasi Java (JAAS) . Seperti namanya, JAAS menjelaskan bagaimana otentikasi dan otorisasi harus dilakukan:
  • " Otentikasi ": Diterjemahkan dari bahasa Yunani, "authentikos" berarti "nyata, asli". Artinya, autentikasi adalah ujian keaslian. Bahwa siapa pun yang diautentikasi adalah benar-benar seperti yang mereka katakan.

  • " Otorisasi ": diterjemahkan dari bahasa Inggris berarti "izin". Artinya, otorisasi adalah kontrol akses yang dilakukan setelah otentikasi berhasil.

Artinya, JAAS adalah tentang menentukan siapa yang meminta akses ke sumber daya dan membuat keputusan apakah dia dapat memperoleh akses tersebut. Sebuah analogi kecil dari kehidupan: Anda sedang mengemudi di sepanjang jalan dan seorang inspektur menghentikan Anda. Harap berikan dokumen - otentikasi. Bisakah Anda mengendarai mobil dengan dokumen - otorisasi. Atau misalnya Anda ingin membeli alkohol di toko. Pertama, Anda dimintai paspor - otentikasi. Selanjutnya, berdasarkan usia Anda, diputuskan apakah Anda memenuhi syarat untuk membeli alkohol. Ini adalah otorisasi. Dalam aplikasi web, login sebagai pengguna (memasukkan nama pengguna dan kata sandi) adalah otentikasi. Dan menentukan halaman mana yang bisa Anda buka ditentukan oleh otorisasi. Di sinilah “Layanan Otentikasi dan Otorisasi Java (JAAS)” membantu kami. Saat mempertimbangkan JAAS, penting untuk memahami beberapa konsep utama yang dijelaskan JAAS: Subjek, Prinsipal, Kredensial. Subjek adalah subjek otentikasi. Artinya, ia adalah pembawa atau pemegang hak. Dalam dokumentasi, Subjek didefinisikan sebagai sumber permintaan untuk melakukan suatu tindakan. Subjek atau sumber harus dideskripsikan dan untuk tujuan ini digunakan Prinsipal, yang dalam bahasa Rusia kadang juga disebut prinsipal. Artinya, setiap Kepala Sekolah merupakan representasi suatu Subyek dari sudut pandang tertentu. Agar lebih jelas, mari kita beri contoh: Orang tertentu adalah Subjek. Dan yang berikut ini dapat bertindak sebagai Kepala Sekolah:
  • surat izin mengemudinya sebagai representasi seseorang sebagai pengguna jalan
  • paspornya, sebagai representasi seseorang sebagai warga negaranya
  • paspor asingnya, sebagai representasi seseorang sebagai peserta hubungan internasional
  • kartu perpustakaannya di perpustakaan, sebagai representasi seseorang sebagai pembaca yang melekat pada perpustakaan
Selain itu, Subjek memiliki seperangkat “Kredensial”, yang berarti “identitas” dalam bahasa Inggris. Beginilah cara Subjek menegaskan bahwa dia adalah dia. Misalnya, kata sandi pengguna dapat berupa Kredensial. Atau objek apa pun yang dapat digunakan pengguna untuk mengonfirmasi bahwa dia benar-benar dirinya. Sekarang mari kita lihat bagaimana JAAS digunakan dalam aplikasi web.
JAAS - Pengantar Teknologi (Bagian 1) - 3

aplikasi web

Jadi, kita memerlukan aplikasi web. Sistem pembangunan proyek otomatis Gradle akan membantu kita membuatnya. Berkat penggunaan Gradle, dengan menjalankan perintah kecil, kita dapat merakit proyek Java dalam format yang kita perlukan, secara otomatis membuat struktur direktori yang diperlukan, dan banyak lagi. Anda dapat membaca lebih lanjut tentang Gradle dalam ikhtisar singkat: " Pengantar Singkat tentang Gradle " atau dalam dokumentasi resmi " Memulai Gradle ". Kita perlu menginisialisasi proyek (Inisialisasi), dan untuk tujuan ini Gradle memiliki plugin khusus: “ Gradle Init Plugin ” (Init adalah kependekan dari Inisialisasi, mudah diingat). Untuk menggunakan plugin ini, jalankan perintah pada baris perintah:
gradle init --type java-application
Setelah berhasil diselesaikan, kita akan memiliki proyek Java. Sekarang mari buka skrip build proyek kita untuk diedit. Skrip pembangunan adalah file bernama build.gradle, yang menjelaskan nuansa pembangunan aplikasi. Oleh karena itu namanya, skrip pembuatan. Kita dapat mengatakan bahwa ini adalah skrip pembuatan proyek. Gradle adalah alat serbaguna yang kemampuan dasarnya diperluas dengan plugin. Oleh karena itu, pertama-tama, mari kita perhatikan blok “plugin”:
plugins {
    id 'java'
    id 'application'
}
Secara default, Gradle, sesuai dengan apa yang kami tentukan " --type java-application", telah menyiapkan sekumpulan beberapa plugin inti, yaitu plugin yang disertakan dalam distribusi Gradle itu sendiri. Jika Anda membuka bagian "Dokumen" (yaitu, dokumentasi) di situs web gradle.org , lalu di sebelah kiri daftar topik di bagian "Referensi" kita melihat bagian " Plugin Inti ", mis. bagian dengan deskripsi plugin yang sangat mendasar ini. Mari kita pilih plugin yang kita butuhkan, dan bukan plugin yang dibuat Gradle untuk kita. Menurut dokumentasi, " Gradle Java Plugin " menyediakan operasi dasar dengan kode Java, seperti kompilasi kode sumber. Selain itu, menurut dokumentasi, " Plugin aplikasi Gradle " memberi kita alat untuk bekerja dengan "aplikasi JVM yang dapat dieksekusi", yaitu. dengan aplikasi java yang dapat diluncurkan sebagai aplikasi mandiri (misalnya aplikasi konsol atau aplikasi dengan UI sendiri). Ternyata kita tidak membutuhkan plugin “aplikasi”, karena… kita tidak memerlukan aplikasi mandiri, kita memerlukan aplikasi web. Mari kita hapus. Serta pengaturan “mainClassName”, yang hanya diketahui oleh plugin ini. Selanjutnya, di bagian " Pengemasan dan distribusi " yang sama di mana link ke dokumentasi Plugin Aplikasi disediakan, terdapat link ke Plugin Gradle War. Plugin Gradle War , sebagaimana tercantum dalam dokumentasi, menyediakan dukungan untuk membuat aplikasi web Java dalam format perang. Dalam format WAR berarti arsip WAR akan dibuat sebagai pengganti arsip JAR. Sepertinya inilah yang kita perlukan. Juga, seperti yang tertulis dalam dokumentasi, "Plugin Perang memperluas plugin Java". Artinya, kita bisa mengganti plugin java dengan plugin perang. Oleh karena itu, blok plugin kami pada akhirnya akan terlihat seperti ini:
plugins {
    id 'war'
}
Juga dalam dokumentasi untuk "Plugin Gradle War" dikatakan bahwa plugin tersebut menggunakan "Tata Letak Proyek" tambahan. Tata letak diterjemahkan dari bahasa Inggris sebagai lokasi. Artinya, plugin perang secara default mengharapkan keberadaan lokasi file tertentu yang akan digunakan untuk tugasnya. Ini akan menggunakan direktori berikut untuk menyimpan file aplikasi web: src/main/webapp Perilaku plugin dijelaskan sebagai berikut:
JAAS - Pengantar Teknologi (Bagian 1) - 4
Artinya, plugin akan memperhitungkan file akun dari lokasi ini saat membuat arsip WAR aplikasi web kita. Selain itu, dokumentasi Plugin Gradle War menyatakan bahwa direktori ini akan menjadi "root dari arsip". Dan sudah di dalamnya kita bisa membuat direktori WEB-INF dan menambahkan file web.xml disana. File macam apa ini? web.xml- ini adalah "Deskriptor Penerapan" atau "deskriptor penerapan". Ini adalah file yang menjelaskan cara mengkonfigurasi aplikasi web kita agar berfungsi. File ini menentukan permintaan apa yang akan ditangani aplikasi kita, pengaturan keamanan, dan banyak lagi. Pada intinya, ini agak mirip dengan file manifes dari file JAR (lihat " Bekerja dengan File Manifes: Dasar-dasar "). File Manifest memberitahukan cara bekerja dengan Aplikasi Java (yaitu arsip JAR), dan web.xml memberitahukan cara bekerja dengan Aplikasi Web Java (yaitu arsip WAR). Konsep "Deployment Descriptor" tidak muncul dengan sendirinya, tetapi dijelaskan dalam dokumen " Spesifikasi Servlet API"". Aplikasi web Java apa pun bergantung pada "API Servlet" ini. Penting untuk dipahami bahwa ini adalah API - yaitu, ini adalah deskripsi dari beberapa kontrak interaksi. Aplikasi web bukanlah aplikasi independen. Mereka berjalan di server web , yang menyediakan komunikasi jaringan dengan pengguna. Artinya, server web adalah semacam "wadah" untuk aplikasi web. Hal ini logis, karena kita ingin menulis logika aplikasi web, yaitu halaman apa yang akan dilihat pengguna dan bagaimana caranya. mereka harus bereaksi terhadap tindakan pengguna. Dan kami tidak ingin menulis kode tentang bagaimana pesan akan dikirim ke pengguna, bagaimana byte informasi akan ditransfer dan hal-hal tingkat rendah dan sangat menuntut kualitas lainnya. Selain itu, ternyata aplikasi web semuanya berbeda, tetapi transfer datanya sama, yaitu satu juta pemrogram harus menulis kode untuk tujuan yang sama berulang kali. Jadi server web bertanggung jawab atas beberapa interaksi pengguna dan pertukaran data, dan aplikasi web serta pengembang bertanggung jawab untuk menghasilkan data tersebut. Dan untuk menghubungkan kedua bagian ini, mis. server web dan aplikasi web, Anda memerlukan kontrak untuk interaksinya, mis. aturan apa yang akan mereka ikuti untuk melakukan ini? Untuk menggambarkan kontrak, seperti apa interaksi antara aplikasi web dan server web, Servlet API diciptakan. Menariknya, meskipun Anda menggunakan kerangka kerja seperti Spring, masih ada API Servlet yang berjalan di baliknya. Artinya, Anda menggunakan Spring, dan Spring bekerja dengan Servlet API untuk Anda. Ternyata proyek aplikasi web kita harus bergantung pada Servlet API. Dalam hal ini, Servlet API akan menjadi ketergantungan. Seperti yang kita ketahui, Gradle juga memungkinkan Anda mendeskripsikan dependensi proyek secara deklaratif. Plugin menjelaskan bagaimana dependensi dapat dikelola. Misalnya, Plugin Java Gradle memperkenalkan metode manajemen ketergantungan "testImplementation", yang menyatakan bahwa ketergantungan tersebut hanya diperlukan untuk pengujian. Namun Plugin Gradle War menambahkan metode manajemen ketergantungan "providedCompile", yang menyatakan bahwa ketergantungan tersebut tidak akan disertakan dalam arsip WAR aplikasi web kita. Mengapa kami tidak menyertakan Servlet API dalam arsip WAR kami? Karena Servlet API akan diberikan ke aplikasi web kita oleh web server itu sendiri. Jika server web menyediakan API Servlet, maka server tersebut disebut wadah servlet. Oleh karena itu, server web bertanggung jawab untuk menyediakan API Servlet kepada kami, dan merupakan tanggung jawab kami untuk menyediakan ServletAPI hanya pada saat kode dikompilasi. Itu sebabnya providedCompile. Dengan demikian, blok dependensi akan terlihat seperti ini:
dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
    testImplementation 'junit:junit:4.12'
}
Jadi, mari kembali ke file web.xml. Secara default, Gradle tidak membuat Deployment Descriptor apa pun, jadi kita perlu melakukannya sendiri. Mari kita buat direktori src/main/webapp/WEB-INF, dan di dalamnya kita akan membuat file XML bernama web.xml. Sekarang mari kita buka "Spesifikasi Java Servlet" itu sendiri dan bab " BAB 14 Deployment Descriptor ". Sebagaimana dinyatakan dalam "14.3 Deployment Descriptor", dokumen XML Deployment Descriptor dijelaskan dengan skema http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd . Skema XML menjelaskan elemen-elemen apa saja yang terdapat dalam sebuah dokumen dan bagaimana urutan kemunculannya. Mana yang wajib dan mana yang tidak. Secara umum, ini menjelaskan struktur dokumen dan memungkinkan Anda memeriksa apakah dokumen XML dibuat dengan benar. Sekarang mari kita gunakan contoh dari bab " 14.5 Contoh ", tetapi skemanya harus ditentukan untuk versi 3.1, yaitu.
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd
Yang kosong kami web.xmlakan terlihat seperti ini:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>JAAS Example</display-name>
</web-app>
Sekarang mari kita jelaskan servlet yang akan kita lindungi menggunakan JAAS. Sebelumnya, Gradle membuat kelas App untuk kita. Mari kita ubah menjadi servlet. Sebagaimana dinyatakan dalam spesifikasi di " BAB 2 Antarmuka Servlet ", bahwa " Untuk sebagian besar tujuan, Pengembang akan memperluas HttpServlet untuk mengimplementasikan servlet mereka ", yaitu, untuk menjadikan suatu kelas menjadi servlet, Anda perlu mewarisi kelas ini dari HttpServlet:
public class App extends HttpServlet {
	public String getGreeting() {
        return "Secret!";
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().print(getGreeting());
    }
}
Seperti yang kami katakan, Servlet API adalah kontrak antara server dan aplikasi web kami. Kontrak ini memungkinkan kita untuk menjelaskan bahwa ketika pengguna menghubungi server, server akan menghasilkan permintaan dari pengguna dalam bentuk objek HttpServletRequestdan meneruskannya ke servlet. Ini juga akan menyediakan objek kepada servlet HttpServletResponsesehingga servlet dapat menulis respons terhadap objek tersebut untuk pengguna. Setelah servlet selesai berjalan, server akan dapat memberikan respons kepada pengguna berdasarkan servlet tersebut HttpServletResponse. Artinya, servlet tidak berkomunikasi langsung dengan pengguna, melainkan hanya dengan server. Agar server mengetahui bahwa kita memiliki servlet dan untuk permintaan apa servlet itu perlu digunakan, kita perlu memberi tahu server tentang hal ini di deskriptor penerapan:
<servlet>
	<servlet-name>app</servlet-name>
	<servlet-class>jaas.App</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>app</servlet-name>
	<url-pattern>/secret</url-pattern>
</servlet-mapping>
Dalam hal ini, semua permintaan /secrettidak akan dialamatkan ke satu servlet kita dengan nama appyang sesuai dengan kelasnya jaas.App. Seperti yang kami katakan sebelumnya, aplikasi web hanya dapat diterapkan di server web. Web server dapat diinstall secara terpisah (standalone). Namun untuk keperluan tinjauan ini, opsi alternatif cocok - berjalan di server tertanam. Ini berarti bahwa server akan dibuat dan diluncurkan secara terprogram (plugin akan melakukan ini untuk kita), dan pada saat yang sama aplikasi web kita akan diterapkan di dalamnya. Sistem pembangunan Gradle memungkinkan Anda menggunakan plugin " Gradle Gretty Plugin " untuk tujuan berikut:
plugins {
    id 'war'
    id 'org.gretty' version '2.2.0'
}
Selain itu, plugin Gretty memiliki dokumentasi yang bagus . Mari kita mulai dengan fakta bahwa plugin Gretty memungkinkan Anda untuk beralih di antara server web yang berbeda. Hal ini dijelaskan secara lebih rinci dalam dokumentasi: " Beralih antar kontainer servlet ". Mari beralih ke Tomcat, karena... ini adalah salah satu yang paling populer digunakan, dan juga memiliki dokumentasi yang baik dan banyak contoh serta masalah yang dianalisis:
gretty {
    // Переключаемся с дефолтного Jetty на Tomcat
    servletContainer = 'tomcat8'
    // Укажем Context Path, он же Context Root
    contextPath = '/jaas'
}
Sekarang kita dapat menjalankan "gradle appRun" dan kemudian aplikasi web kita akan tersedia di http://localhost:8080/jaas/secret
JAAS - Pengantar Teknologi (Bagian 1) - 5
Penting untuk memeriksa bahwa wadah servlet dipilih oleh Tomcat (lihat #1) dan memeriksa di alamat mana aplikasi web kita tersedia (lihat #2).
JAAS - Pengantar Teknologi (Bagian 1) - 6

Autentikasi

Pengaturan otentikasi sering kali terdiri dari dua bagian: pengaturan di sisi server dan pengaturan di sisi aplikasi web yang berjalan di server ini. Pengaturan keamanan aplikasi web tidak dapat tidak berinteraksi dengan pengaturan keamanan server web, jika tidak ada alasan lain selain itu aplikasi web tidak dapat tidak berinteraksi dengan server web. Tidak sia-sia kami beralih ke Tomcat, karena... Tomcat memiliki arsitektur yang dijelaskan dengan baik (lihat " Arsitektur Apache Tomcat 8 "). Dari gambaran arsitektur ini terlihat jelas bahwa Tomcat sebagai web server merepresentasikan aplikasi web dalam konteks tertentu yang disebut “ Konteks Tomcat ”. Konteks ini memungkinkan setiap aplikasi web memiliki pengaturannya sendiri, terisolasi dari aplikasi web lainnya. Selain itu, aplikasi web dapat mempengaruhi pengaturan konteks ini. Fleksibel dan nyaman. Untuk pemahaman yang lebih mendalam, kami sarankan untuk membaca artikel " Memahami Kontainer Konteks Tomcat " dan bagian dokumentasi Tomcat " Kontainer Konteks ". Sebagaimana dinyatakan di atas, aplikasi web kita dapat mempengaruhi Konteks Tomcat aplikasi kita menggunakan file /META-INF/context.xml. Dan salah satu pengaturan yang sangat penting yang dapat kita pengaruhi adalah Ranah Keamanan. Alam Keamanan adalah semacam “area keamanan”. Area yang pengaturan keamanan spesifiknya ditentukan. Oleh karena itu, saat menggunakan Ranah Keamanan, kami menerapkan pengaturan keamanan yang ditentukan untuk Ranah ini. Alam Keamanan dikelola oleh sebuah wadah, mis. server web, bukan aplikasi web kami. Kami hanya dapat memberi tahu server cakupan keamanan mana yang perlu diperluas ke aplikasi kami. Dokumentasi Tomcat di bagian " Komponen Realm " menjelaskan Realm sebagai kumpulan data tentang pengguna dan peran mereka untuk melakukan otentikasi. Tomcat menyediakan serangkaian implementasi Ranah Keamanan yang berbeda, salah satunya adalah " Jaas Realm ". Setelah memahami sedikit terminologi, mari kita uraikan Konteks Tomcat pada file /META-INF/context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Realm className="org.apache.catalina.realm.JAASRealm"
           appName="JaasLogin"
           userClassNames="jaas.login.UserPrincipal"
           roleClassNames="jaas.login.RolePrincipal"
           configFile="jaas.config" />
</Context>
appName- nama aplikasi. Tomcat akan mencoba mencocokkan nama ini dengan nama yang ditentukan dalam file configFile. configFile- ini adalah "file konfigurasi login". Contohnya dapat dilihat pada dokumentasi JAAS: " Lampiran B: Contoh Konfigurasi Login ". Selain itu, penting agar file ini dicari terlebih dahulu di sumber daya. Oleh karena itu, aplikasi web kita dapat menyediakan file ini sendiri. Atribut userClassNamesdan roleClassNamesberisi indikasi kelas yang mewakili kepala sekolah pengguna. JAAS memisahkan konsep "pengguna" dan "peran" sebagai dua konsep yang berbeda java.security.Principal. Mari kita uraikan kelas-kelas di atas. Mari buat implementasi paling sederhana untuk prinsipal pengguna:
public class UserPrincipal implements Principal {
    private String name;
    public UserPrincipal(String name) {
        this.name = name;
    }
    @Override
    public String getName() {
        return name;
    }
}
Kami akan mengulangi implementasi yang sama untuk RolePrincipal. Seperti yang Anda lihat dari antarmuka, hal utama bagi Principal adalah menyimpan dan mengembalikan beberapa nama (atau ID) yang mewakili Principal. Sekarang, kami memiliki Ranah Keamanan, kami memiliki kelas-kelas utama. Tetap mengisi file dari configFileatribut " " alias login configuration file. Deskripsinya dapat ditemukan di dokumentasi Tomcat: " The Realm Component ".
JAAS - Pengantar Teknologi (Bagian 1) - 7
Artinya, kita dapat menempatkan pengaturan JAAS Login Config di sumber daya aplikasi web kita dan berkat Tomcat Context kita akan dapat menggunakannya. File ini harus tersedia sebagai sumber daya untuk ClassLoader, jadi jalurnya harus seperti ini: \src\main\resources\jaas.config Mari kita atur konten file ini:
JaasLogin {
    jaas.login.JaasLoginModule required debug=true;
};
Perlu dicatat bahwa context.xmlnama yang sama digunakan di sini dan di dalam. Ini memetakan Ranah Keamanan ke LoginModule. Jadi, Konteks Tomcat memberi tahu kita kelas mana yang mewakili prinsipal, serta LoginModule mana yang akan digunakan. Yang harus kita lakukan adalah mengimplementasikan LoginModule ini. LoginModule mungkin adalah salah satu hal paling menarik di JAAS. Dokumentasi resmi akan membantu kami dalam mengembangkan LoginModule: " Layanan Otentikasi dan Otorisasi Java (JAAS): Panduan Pengembang LoginModule ". Mari kita implementasi modul login. Mari kita buat kelas yang mengimplementasikan antarmuka LoginModule:
public class JaasLoginModule implements LoginModule {
}
Pertama kami menjelaskan metode inisialisasi LoginModule:
private CallbackHandler handler;
private Subject subject;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, <String, ?> sharedState, Map<String, ?> options) {
	handler = callbackHandler;
	this.subject = subject;
}
Cara ini akan menyimpan Subject, yang selanjutnya akan kami autentikasi dan diisi dengan informasi tentang prinsipal. Kami juga akan menabung untuk penggunaan di masa depan CallbackHandler, yang diberikan kepada kami. Dengan bantuan, CallbackHandlerkami dapat meminta berbagai informasi tentang subjek otentikasi nanti. Anda dapat membaca lebih lanjut tentang hal ini CallbackHandlerdi bagian dokumentasi yang sesuai: " Panduan Referensi JAAS: CallbackHandler ". Selanjutnya, metode loginotentikasi dijalankan Subject. Ini adalah tahap pertama otentikasi:
@Override
public boolean login() throws LoginException {
	// Добавляем колбэки
	Callback[] callbacks = new Callback[2];
	callbacks[0] = new NameCallback("login");
	callbacks[1] = new PasswordCallback("password", true);
	// При помощи колбэков получаем через CallbackHandler логин и пароль
	try {
		handler.handle(callbacks);
		String name = ((NameCallback) callbacks[0]).getName();
		String password = String.valueOf(((PasswordCallback) callbacks[1]).getPassword());
		// Далее выполняем валидацию.
		// Тут просто для примера проверяем определённые значения
		if (name != null && name.equals("user123") && password != null && password.equals("pass123")) {
			// Сохраняем информацию, которая будет использована в методе commit
			// Не "пачкаем" Subject, т.к. не факт, что commit выполнится
			// Для примера проставим группы вручную, "хардcodeно".
			login = name;
			userGroups = new ArrayList<String>();
			userGroups.add("admin");
			return true;
		} else {
			throw new LoginException("Authentication failed");
		}
	} catch (IOException | UnsupportedCallbackException e) {
		throw new LoginException(e.getMessage());
	}
}
Penting bagi loginkita untuk tidak mengubah Subject. Perubahan tersebut seharusnya hanya terjadi pada metode konfirmasi commit. Selanjutnya, kita harus menjelaskan metode untuk mengonfirmasi otentikasi yang berhasil:
@Override
public boolean commit() throws LoginException {
	userPrincipal = new UserPrincipal(login);
	subject.getPrincipals().add(userPrincipal);
	if (userGroups != null && userGroups.size() > 0) {
		for (String groupName : userGroups) {
			rolePrincipal = new RolePrincipal(groupName);
			subject.getPrincipals().add(rolePrincipal);
		}
	}
	return true;
}
Mungkin terasa aneh untuk memisahkan metode logindan commit. Tapi intinya modul login bisa digabungkan. Dan agar autentikasi berhasil, mungkin diperlukan beberapa modul login agar berhasil. Dan hanya jika semua modul yang diperlukan telah berfungsi, simpan perubahannya. Ini adalah otentikasi tahap kedua. Mari selesaikan dengan metode abortdan logout:
@Override
public boolean abort() throws LoginException {
	return false;
}
@Override
public boolean logout() throws LoginException {
	subject.getPrincipals().remove(userPrincipal);
	subject.getPrincipals().remove(rolePrincipal);
	return true;
}
Metode ini abortdipanggil ketika tahap pertama otentikasi gagal. Metode ini logoutdipanggil ketika sistem logout. Setelah menerapkan Login Moduledan mengkonfigurasinya Security Realm, Sekarang kita perlu menunjukkan web.xmlfakta bahwa kita ingin menggunakan yang spesifik Login Config:
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>JaasLogin</realm-name>
</login-config>
Kami menentukan nama Ranah Keamanan kami dan menentukan Metode Otentikasi - BASIC. Ini adalah salah satu jenis otentikasi yang dijelaskan dalam API Servlet di bagian " 13.6 Otentikasi ". Tetap n
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION