JavaRush /Blog Java /Random-MS /JAAS - Pengenalan kepada Teknologi (Bahagian 1)

JAAS - Pengenalan kepada Teknologi (Bahagian 1)

Diterbitkan dalam kumpulan
Keselamatan capaian telah dilaksanakan di Java untuk masa yang agak lama dan seni bina untuk menyediakan keselamatan ini dipanggil JAAS - Perkhidmatan Pengesahan dan Kebenaran Java. Semakan ini akan cuba merungkai misteri apa itu pengesahan, kebenaran dan apa kaitan JAAS dengannya. Bagaimana JAAS berkawan dengan Servlet API, dan tempat mereka menghadapi masalah dalam hubungan mereka.
JAAS - Pengenalan kepada Teknologi (Bahagian 1) - 1

pengenalan

Dalam ulasan ini saya ingin membincangkan topik seperti keselamatan aplikasi web. Java mempunyai beberapa teknologi yang menyediakan keselamatan: Tetapi perbualan kami hari ini adalah mengenai teknologi lain, yang dipanggil "Java Authentication and Authorization Service (JAAS)". Dialah yang menerangkan perkara penting seperti pengesahan dan kebenaran. Mari kita lihat ini dengan lebih terperinci.
JAAS - Pengenalan kepada Teknologi (Bahagian 1) - 2

JAAS

JAAS ialah sambungan kepada Java SE dan diterangkan dalam Panduan Rujukan Java Authentication and Authorization Service (JAAS) . Seperti yang dicadangkan oleh nama teknologi, JAAS menerangkan cara pengesahan dan kebenaran harus dilakukan:
  • " Pengesahan ": Diterjemah daripada bahasa Yunani, "authentikos" bermaksud "sebenar, tulen". Maksudnya, pengesahan adalah ujian ketulenan. Bahawa sesiapa yang disahkan adalah benar-benar yang mereka katakan.

  • " Kebenaran ": diterjemahkan daripada bahasa Inggeris bermaksud "kebenaran". Iaitu, kebenaran ialah kawalan akses yang dilakukan selepas pengesahan berjaya.

Iaitu, JAAS adalah tentang menentukan siapa yang meminta akses kepada sumber dan membuat keputusan sama ada dia boleh mendapatkan akses ini. Analogi kecil dari kehidupan: anda memandu di sepanjang jalan dan seorang pemeriksa menghalang anda. Sila berikan dokumen - pengesahan. Bolehkah anda memandu kereta dengan dokumen - kebenaran. Atau, sebagai contoh, anda ingin membeli alkohol di kedai. Pertama, anda diminta untuk pasport - pengesahan. Seterusnya, berdasarkan umur anda, diputuskan sama ada anda layak untuk membeli alkohol. Ini adalah kebenaran. Dalam aplikasi web, log masuk sebagai pengguna (memasukkan nama pengguna dan kata laluan) adalah pengesahan. Dan menentukan halaman yang anda boleh buka ditentukan oleh kebenaran. Di sinilah "Perkhidmatan Pengesahan dan Kebenaran Java (JAAS)" membantu kami. Apabila mempertimbangkan JAAS, adalah penting untuk memahami beberapa konsep utama yang diterangkan oleh JAAS: Subjek, Pengetua, Tauliah. Subjek ialah subjek pengesahan. Iaitu, ia adalah pemegang atau pemegang hak. Dalam dokumentasi, Subjek ditakrifkan sebagai sumber permintaan untuk melakukan beberapa tindakan. Subjek atau sumber mesti diterangkan dan untuk tujuan ini Pengetua digunakan, yang dalam bahasa Rusia juga kadang-kadang dipanggil pengetua. Maksudnya, setiap Pengetua adalah perwakilan sesuatu Mata Pelajaran dari sudut pandangan tertentu. Untuk menjadikannya lebih jelas, mari kita berikan contoh: Seseorang tertentu ialah Subjek. Dan yang berikut boleh bertindak sebagai Pengetua:
  • lesen memandunya sebagai representasi seseorang sebagai pengguna jalan raya
  • pasportnya, sebagai representasi seseorang sebagai warganegara negaranya
  • pasport asingnya, sebagai representasi seseorang sebagai peserta dalam hubungan antarabangsa
  • kad perpustakaannya di perpustakaan, sebagai representasi seseorang sebagai pembaca yang melekat pada perpustakaan
Selain itu, Subjek mempunyai satu set "Kredential", yang bermaksud "identiti" dalam bahasa Inggeris. Ini adalah bagaimana Subjek mengesahkan bahawa dia adalah dia. Sebagai contoh, kata laluan pengguna boleh menjadi Kredensial. Atau mana-mana objek yang pengguna boleh mengesahkan bahawa dia benar-benar dia. Sekarang mari kita lihat bagaimana JAAS digunakan dalam aplikasi web.
JAAS - Pengenalan kepada Teknologi (Bahagian 1) - 3

aplikasi sesawang

Jadi kami memerlukan aplikasi web. Sistem binaan projek automatik Gradle akan membantu kami menciptanya. Terima kasih kepada penggunaan Gradle, kami boleh, dengan melaksanakan arahan kecil, memasang projek Java dalam format yang kami perlukan, secara automatik mencipta struktur direktori yang diperlukan, dan banyak lagi. Anda boleh membaca lebih lanjut tentang Gradle dalam gambaran ringkas: " Pengenalan Ringkas kepada Gradle " atau dalam dokumentasi rasmi " Gradle Bermula ". Kita perlu memulakan projek (Initialization), dan untuk tujuan ini Gradle mempunyai pemalam khas: " Gradle Init Plugin " (Init ialah singkatan untuk Initialization, mudah diingati). Untuk menggunakan pemalam ini, jalankan arahan pada baris arahan:
gradle init --type java-application
Selepas berjaya disiapkan, kami akan mempunyai projek Java. Sekarang mari buka skrip binaan projek kami untuk diedit. Skrip binaan ialah fail yang dipanggil build.gradle, yang menerangkan nuansa binaan aplikasi. Oleh itu namanya, bina skrip. Kita boleh mengatakan bahawa ini adalah skrip binaan projek. Gradle ialah alat serba boleh, keupayaan asasnya diperluaskan dengan pemalam. Oleh itu, pertama sekali, mari kita perhatikan blok "plugin":
plugins {
    id 'java'
    id 'application'
}
Secara lalai, Gradle, mengikut apa yang kami nyatakan " --type java-application", telah menyediakan set beberapa pemalam teras, iaitu pemalam yang disertakan dalam pengedaran Gradle itu sendiri. Jika anda pergi ke bahagian "Dokumen" (iaitu dokumentasi) di tapak web gradle.org , kemudian di sebelah kiri dalam senarai topik dalam bahagian "Rujukan" kita melihat bahagian " Pemalam Teras ", i.e. bahagian dengan penerangan tentang pemalam yang sangat asas ini. Mari kita pilih betul-betul pemalam yang kita perlukan, dan bukannya pemalam yang Gradle hasilkan untuk kita. Menurut dokumentasi, " Gradle Java Plugin " menyediakan operasi asas dengan kod Java, seperti menyusun kod sumber. Selain itu, menurut dokumentasi, " Pemalam aplikasi Gradle " memberikan kami alat untuk bekerja dengan "aplikasi JVM boleh laku", i.e. dengan aplikasi java yang boleh dilancarkan sebagai aplikasi kendiri (contohnya, aplikasi konsol atau aplikasi dengan UI sendiri). Ternyata kita tidak memerlukan pemalam "aplikasi", kerana... kami tidak memerlukan aplikasi kendiri, kami memerlukan aplikasi web. Mari padamkannya. Serta tetapan "mainClassName", yang hanya diketahui oleh pemalam ini. Selanjutnya, dalam bahagian " Pembungkusan dan pengedaran " yang sama di mana pautan ke dokumentasi Pemalam Aplikasi disediakan, terdapat pautan ke Pemalam Perang Gradle. Gradle War Plugin , seperti yang dinyatakan dalam dokumentasi, menyediakan sokongan untuk mencipta aplikasi web Java dalam format perang. Dalam format WAR bermakna bahawa bukannya arkib JAR, arkib WAR akan dibuat. Nampaknya ini yang kita perlukan. Juga, seperti yang dinyatakan dalam dokumentasi, "Pemalam Perang memanjangkan pemalam Java". Iaitu, kita boleh menggantikan plugin java dengan plugin perang. Oleh itu, blok pemalam kami akhirnya akan kelihatan seperti ini:
plugins {
    id 'war'
}
Juga dalam dokumentasi untuk "Gradle War Plugin" dikatakan bahawa plugin menggunakan tambahan "Project Layout". Susun atur diterjemahkan daripada bahasa Inggeris sebagai lokasi. Iaitu, pemalam perang secara lalai menjangkakan kewujudan lokasi tertentu fail yang akan digunakan untuk tugasnya. Ia akan menggunakan direktori berikut untuk menyimpan fail aplikasi web: src/main/webapp Kelakuan pemalam diterangkan seperti berikut:
JAAS - Pengenalan kepada Teknologi (Bahagian 1) - 4
Iaitu, pemalam akan mengambil kira fail dari lokasi ini semasa membina arkib WAR aplikasi web kami. Selain itu, dokumentasi Gradle War Plugin mengatakan bahawa direktori ini akan menjadi "akar arkib". Dan sudah di dalamnya kita boleh mencipta direktori WEB-INF dan menambah fail web.xml di sana. Apakah jenis fail ini? web.xml- ini ialah "Deskriptor Deployment" atau "Descriptor Deskriptor". Ini ialah fail yang menerangkan cara mengkonfigurasi aplikasi web kami untuk berfungsi. Fail ini menentukan permintaan yang akan dikendalikan oleh aplikasi kami, tetapan keselamatan dan banyak lagi. Pada terasnya, ia agak serupa dengan fail manifes daripada fail JAR (lihat " Bekerja dengan Fail Manifes: Asas "). Fail Manifest memberitahu cara untuk bekerja dengan Aplikasi Java (iaitu arkib JAR), dan web.xml memberitahu cara untuk bekerja dengan Aplikasi Web Java (iaitu arkib WAR). Konsep "Deskriptor Deployment" tidak timbul dengan sendirinya, tetapi diterangkan dalam dokumen " Spesifikasi API Servlet"". Mana-mana aplikasi web Java bergantung pada "Servlet API" ini. Adalah penting untuk memahami bahawa ini ialah API - iaitu, ia adalah perihalan beberapa kontrak interaksi. Aplikasi web bukan aplikasi bebas. Ia dijalankan pada pelayan web , yang menyediakan komunikasi rangkaian dengan pengguna. Iaitu, pelayan web adalah sejenis "bekas" untuk aplikasi web. Ini adalah logik, kerana kami ingin menulis logik aplikasi web, iaitu halaman apa yang pengguna akan lihat dan bagaimana mereka harus bertindak balas terhadap tindakan pengguna. Dan kami tidak mahu menulis kod untuk bagaimana mesej akan dihantar kepada pengguna, cara bait maklumat akan dipindahkan dan perkara peringkat rendah dan sangat menuntut kualiti yang lain. Selain itu, ternyata aplikasi web semuanya berbeza, tetapi pemindahan data adalah sama. Iaitu, sejuta pengaturcara perlu menulis kod untuk tujuan yang sama berulang kali. Jadi pelayan web bertanggungjawab untuk beberapa interaksi pengguna dan pertukaran data, dan aplikasi web dan pembangun bertanggungjawab untuk menjana data tersebut. Dan untuk menyambung dua bahagian ini, i.e. pelayan web dan aplikasi web, anda memerlukan kontrak untuk interaksi mereka, i.e. apakah peraturan yang akan mereka ikuti untuk melakukan ini? Untuk menerangkan kontrak, bagaimana interaksi antara aplikasi web dan pelayan web sepatutnya kelihatan, API Servlet telah dicipta. Menariknya, walaupun anda menggunakan rangka kerja seperti Spring, masih terdapat Servlet API yang berjalan di bawah hud. Iaitu, anda menggunakan Spring dan Spring berfungsi dengan Servlet API untuk anda. Ternyata projek aplikasi web kami mesti bergantung pada API Servlet. Dalam kes ini, Servlet API akan menjadi kebergantungan. Seperti yang kita ketahui, Gradle juga membenarkan anda untuk menerangkan kebergantungan projek dengan cara deklaratif. Pemalam menerangkan cara kebergantungan boleh diurus. Sebagai contoh, Java Gradle Plugin memperkenalkan kaedah pengurusan pergantungan "testImplementation", yang mengatakan bahawa pergantungan sedemikian hanya diperlukan untuk ujian. Tetapi Gradle War Plugin menambah kaedah pengurusan pergantungan "providedCompile", yang mengatakan bahawa pergantungan sedemikian tidak akan disertakan dalam arkib WAR aplikasi web kami. Mengapa kami tidak memasukkan Servlet API dalam arkib WAR kami? Kerana API Servlet akan diberikan kepada aplikasi web kami oleh pelayan web itu sendiri. Jika pelayan web menyediakan API Servlet, maka pelayan itu dipanggil bekas servlet. Oleh itu, adalah menjadi tanggungjawab pelayan web untuk memberikan kami Servlet API, dan menjadi tanggungjawab kami untuk menyediakan ServletAPI hanya pada masa kod disusun. sebab tu providedCompile. Oleh itu, blok dependencies akan kelihatan seperti ini:
dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
    testImplementation 'junit:junit:4.12'
}
Jadi, mari kita kembali ke fail web.xml. Secara lalai, Gradle tidak mencipta sebarang Deskriptor Deployment, jadi kami perlu melakukannya sendiri. Mari kita cipta direktori src/main/webapp/WEB-INF, dan di dalamnya kita akan mencipta fail XML yang dipanggil web.xml. Sekarang mari kita buka "Java Servlet Specification" itu sendiri dan bab " BAB 14 Deployment Descriptor ". Seperti yang dinyatakan dalam "14.3 Deskriptor Deskriptor", dokumen XML Deskriptor Deployment diterangkan oleh skema http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd . Skema XML menghuraikan elemen yang boleh terdiri daripada dokumen dan dalam susunan yang sepatutnya ia muncul. Mana yang wajib dan mana yang tidak. Secara umum, ia menerangkan struktur dokumen dan membolehkan anda menyemak sama ada dokumen XML disusun dengan betul. Sekarang mari kita gunakan contoh dari bab " 14.5 Contoh ", tetapi skema mesti ditentukan untuk versi 3.1, i.e.
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd
Yang kosong kami web.xmlakan kelihatan 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 terangkan servlet yang akan kita lindungi menggunakan JAAS. Sebelum ini, Gradle menjana kelas Apl untuk kami. Mari jadikan servlet. Seperti yang dinyatakan dalam spesifikasi dalam " BAB 2 Antara Muka Servlet ", bahawa " Untuk kebanyakan tujuan, Pembangun akan melanjutkan HttpServlet untuk melaksanakan servlet mereka ", iaitu, untuk menjadikan kelas sebagai servlet, anda perlu mewarisi kelas ini daripada 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 ialah kontrak antara pelayan dan aplikasi web kami. Kontrak ini membolehkan kami menerangkan bahawa apabila pengguna menghubungi pelayan, pelayan akan menjana permintaan daripada pengguna dalam bentuk objek HttpServletRequestdan menghantarnya kepada servlet. Ia juga akan menyediakan servlet dengan objek HttpServletResponsesupaya servlet boleh menulis respons kepadanya untuk pengguna. Setelah servlet selesai dijalankan, pelayan akan dapat memberikan respons berdasarkannya kepada pengguna HttpServletResponse. Iaitu, servlet tidak berkomunikasi secara langsung dengan pengguna, tetapi hanya dengan pelayan. Untuk membolehkan pelayan mengetahui bahawa kami mempunyai servlet dan untuk permintaan apa yang perlu digunakan, kami perlu memberitahu pelayan tentang perkara ini dalam deskriptor penggunaan:
<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 kes ini, semua permintaan /secrettidak akan dialamatkan kepada satu servlet kami mengikut nama app, yang sepadan dengan kelas jaas.App. Seperti yang kami katakan sebelum ini, aplikasi web hanya boleh digunakan pada pelayan web. Pelayan web boleh dipasang secara berasingan (berdiri sendiri). Tetapi untuk tujuan semakan ini, pilihan alternatif adalah sesuai - berjalan pada pelayan terbenam. Ini bermakna pelayan akan dibuat dan dilancarkan secara pemrograman (pemalam akan melakukan ini untuk kami), dan pada masa yang sama aplikasi web kami akan digunakan padanya. Sistem binaan Gradle membolehkan anda menggunakan pemalam " Gradle Gretty Plugin " untuk tujuan ini:
plugins {
    id 'war'
    id 'org.gretty' version '2.2.0'
}
Selain itu, pemalam Gretty mempunyai dokumentasi yang baik . Mari kita mulakan dengan fakta bahawa pemalam Gretty membolehkan anda bertukar antara pelayan web yang berbeza. Ini diterangkan dengan lebih terperinci dalam dokumentasi: " Bertukar antara bekas servlet ". Mari bertukar kepada Tomcat, kerana... ia adalah salah satu yang paling popular digunakan, dan juga mempunyai dokumentasi yang baik dan banyak contoh dan masalah yang dianalisis:
gretty {
    // Переключаемся с дефолтного Jetty на Tomcat
    servletContainer = 'tomcat8'
    // Укажем Context Path, он же Context Root
    contextPath = '/jaas'
}
Kini kami boleh menjalankan "gradle appRun" dan kemudian aplikasi web kami akan tersedia di http://localhost:8080/jaas/secret
JAAS - Pengenalan kepada Teknologi (Bahagian 1) - 5
Adalah penting untuk menyemak bahawa bekas servlet dipilih oleh Tomcat (lihat #1) dan semak di alamat mana aplikasi web kami tersedia (lihat #2).
JAAS - Pengenalan kepada Teknologi (Bahagian 1) - 6

Pengesahan

Tetapan pengesahan selalunya terdiri daripada dua bahagian: tetapan pada bahagian pelayan dan tetapan pada sisi aplikasi web yang berjalan pada pelayan ini. Tetapan keselamatan aplikasi web tidak boleh tidak berinteraksi dengan tetapan keselamatan pelayan web, jika tidak ada sebab lain daripada itu aplikasi web tidak boleh tidak berinteraksi dengan pelayan web. Tidak sia-sia kami bertukar kepada Tomcat, kerana... Tomcat mempunyai seni bina yang diterangkan dengan baik (lihat " Seni Bina Apache Tomcat 8 "). Daripada penerangan seni bina ini jelas bahawa Tomcat, sebagai pelayan web, mewakili aplikasi web sebagai konteks tertentu, yang dipanggil " Konteks Tomcat ". Konteks ini membenarkan setiap aplikasi web mempunyai tetapan sendiri, diasingkan daripada aplikasi web lain. Selain itu, aplikasi web boleh mempengaruhi tetapan konteks ini. Fleksibel dan mudah. Untuk pemahaman yang lebih mendalam, kami mengesyorkan membaca artikel " Memahami Bekas Konteks Tomcat " dan bahagian dokumentasi Tomcat " Bekas Konteks ". Seperti yang dinyatakan di atas, aplikasi web kami boleh mempengaruhi Konteks Tomcat aplikasi kami menggunakan /META-INF/context.xml. Dan salah satu tetapan yang sangat penting yang boleh kita pengaruhi ialah Alam Keselamatan. Alam Keselamatan ialah sejenis "kawasan keselamatan". Kawasan yang menetapkan tetapan keselamatan khusus. Sehubungan itu, apabila menggunakan Alam Keselamatan, kami menggunakan tetapan keselamatan yang ditakrifkan untuk Alam ini. Alam Keselamatan diuruskan oleh bekas, i.e. pelayan web, bukan aplikasi web kami. Kami hanya boleh memberitahu pelayan skop keselamatan yang perlu diperluaskan kepada aplikasi kami. Dokumentasi Tomcat dalam bahagian " The Realm Component " menerangkan Alam sebagai koleksi data tentang pengguna dan peranan mereka untuk melaksanakan pengesahan. Tomcat menyediakan satu set pelaksanaan Alam Keselamatan yang berbeza, salah satunya ialah " Alam Jaas ". Setelah memahami sedikit istilah, mari kita terangkan Konteks Tomcat dalam fail /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 cuba memadankan nama ini dengan nama yang dinyatakan dalam configFile. configFile- ini ialah "fail konfigurasi log masuk". Contoh ini boleh dilihat dalam dokumentasi JAAS: " Lampiran B: Contoh Konfigurasi Log Masuk ". Di samping itu, adalah penting bahawa fail ini akan dicari dahulu dalam sumber. Oleh itu, aplikasi web kami boleh menyediakan fail ini sendiri. Atribut userClassNamesdan roleClassNamesmengandungi petunjuk kelas yang mewakili prinsipal pengguna. JAAS memisahkan konsep "pengguna" dan "peranan" sebagai dua konsep berbeza java.security.Principal. Mari kita huraikan kelas di atas. Mari kita buat pelaksanaan paling mudah 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 pelaksanaan yang sama untuk RolePrincipal. Seperti yang anda boleh lihat daripada antara muka, perkara utama bagi Pengetua ialah menyimpan dan mengembalikan beberapa nama (atau ID) yang mewakili Pengetua. Kini, kami mempunyai Alam Keselamatan, kami mempunyai kelas utama. Ia kekal untuk mengisi fail daripada configFileatribut " ", aka login configuration file. Penerangannya boleh didapati dalam dokumentasi Tomcat: " The Realm Component ".
JAAS - Pengenalan kepada Teknologi (Bahagian 1) - 7
Iaitu, kami boleh meletakkan tetapan Konfigurasi Log Masuk JAAS dalam sumber aplikasi web kami dan terima kasih kepada Konteks Tomcat kami akan dapat menggunakannya. Fail ini mesti tersedia sebagai sumber untuk ClassLoader, jadi laluannya hendaklah seperti ini: \src\main\resources\jaas.config Mari kita tetapkan kandungan fail ini:
JaasLogin {
    jaas.login.JaasLoginModule required debug=true;
};
Perlu diingat bahawa context.xmlnama yang sama digunakan di sini dan di dalam. Ini memetakan Alam Keselamatan kepada LoginModule. Jadi, Tomcat Context memberitahu kami kelas mana yang mewakili pengetua, serta LoginModule yang hendak digunakan. Apa yang perlu kita lakukan ialah melaksanakan LoginModule ini. LoginModule mungkin salah satu perkara yang paling menarik dalam JAAS. Dokumentasi rasmi akan membantu kami dalam membangunkan LoginModule: " Java Authentication and Authorization Service (JAAS): LoginModule Developer's Guide ". Mari kita laksanakan modul log masuk. Mari buat kelas yang melaksanakan antara muka LoginModule:
public class JaasLoginModule implements LoginModule {
}
Mula-mula kita menerangkan kaedah permulaan 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;
}
Kaedah ini akan menyimpan Subject, yang akan kami sahkan dan isi dengan maklumat tentang pengetua. Kami juga akan menyimpan untuk kegunaan masa hadapan CallbackHandler, yang diberikan kepada kami. Dengan bantuan, CallbackHandlerkami boleh meminta pelbagai maklumat tentang subjek pengesahan sedikit kemudian. Anda boleh membaca lebih lanjut mengenainya CallbackHandlerdalam bahagian dokumentasi yang sepadan: " Panduan Rujukan JAAS: CallbackHandler ". Seterusnya, kaedah loginuntuk pengesahan dilaksanakan Subject. Ini ialah fasa pertama pengesahan:
@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());
	}
}
Adalah penting bahawa loginkita tidak harus mengubah Subject. Perubahan sedemikian seharusnya hanya berlaku dalam kaedah pengesahan commit. Seterusnya, kita mesti menerangkan kaedah untuk mengesahkan pengesahan yang berjaya:
@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;
}
Ia mungkin kelihatan pelik untuk memisahkan kaedah logindan commit. Tetapi intinya ialah modul log masuk boleh digabungkan. Dan untuk pengesahan yang berjaya, beberapa modul log masuk mungkin perlu berfungsi dengan jayanya. Dan hanya jika semua modul yang diperlukan telah berfungsi, kemudian simpan perubahan. Ini adalah fasa kedua pengesahan. Mari kita selesaikan dengan abortdan kaedah 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;
}
Kaedah abortdipanggil apabila fasa pertama pengesahan gagal. Kaedah logoutdipanggil apabila sistem log keluar. Setelah melaksanakan kami Login Moduledan mengkonfigurasinya Security Realm, Sekarang kami perlu menunjukkan web.xmlfakta bahawa kami ingin menggunakan yang khusus Login Config:
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>JaasLogin</realm-name>
</login-config>
Kami menyatakan nama Alam Keselamatan kami dan menentukan Kaedah Pengesahan - BASIC. Ini adalah salah satu jenis pengesahan yang diterangkan dalam Servlet API dalam bahagian " 13.6 Authentication ". Kekal n
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION