Apache Shiro adalah kerangka keamanan keamanan terbuka yang kuat dan fleksibel yang menangani proses kontrol keamanan yang umum dalam aplikasi tingkat perusahaan seperti otentikasi, otorisasi, manajemen sesi, dan enkripsi pada tingkat berbutir halus. Tujuan utama Apache Shiro adalah kemudahan penggunaan dan pemahaman. Terkadang kontrol proses keamanan bisa sangat rumit, yang merupakan sakit kepala bagi pengembang, tetapi tidak selalu berarti. Kerangka kerja harus menutupi kompleksitas sebanyak mungkin dan mengekspos API yang ringkas dan intuitif, sehingga menyederhanakan pekerjaan pengembang dan memastikan keamanan aplikasi mereka. Kali ini kita akan berbicara tentang cara menggunakan Shiro untuk mengimplementasikan kontrol izin dalam aplikasi web Spring.
Fungsi
Apache Shiro adalah kerangka keamanan aplikasi yang komprehensif dengan banyak fitur. Gambar berikut menunjukkan fungsi terpenting di Shiro:
Tujuan utama Shiro adalah "empat landasan keamanan aplikasi" - otentikasi, otorisasi, manajemen sesi dan enkripsi:
Arsitektur
Dari perspektif holistik, arsitektur Shiro memiliki tiga konsep utama: subjek (subjek, yaitu pengguna), manajer keamanan (manajer keamanan) dan ranah (domain). Gambar berikut menggambarkan hubungan antara komponen -komponen ini:
Komponen -komponen ini dapat dipahami sebagai berikut:
Persiapan data
Dalam aplikasi web, kontrol utama atas keamanan adalah peran, sumber daya, dan izin (peran apa yang dapat mengakses sumber daya apa). Pengguna dapat memiliki banyak peran, dan peran juga dapat mengakses banyak sumber daya, yaitu, peran dapat sesuai dengan banyak izin. Untuk mengimplementasikan desain database, kita perlu membangun setidaknya 5 tabel: tabel pengguna, tabel peran, tabel sumber daya, tabel sumber daya peran, tabel peran pengguna. Struktur 5 tabel ini adalah sebagai berikut:
Tabel Pengguna:
| pengenal | nama belakang | kata sandi |
|---|---|---|
| 1 | Zhang San | 123456 |
| 2 | Li si | 6666666 |
| 3 | Wang Wu | 000000 |
Daftar Peran:
| pengenal | nama rolen |
|---|---|
| 1 | administrator |
| 2 | manajer |
| 3 | staf |
Tabel Sumber Daya:
| pengenal | nama resn |
|---|---|
| 1 | /pengguna/add |
| 2 | /Pengguna/Hapus |
| 3 | /Komponi/Info |
Tabel sumber daya peran:
| pengenal | roleid | Residasi |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
Tabel peran pengguna:
| pengenal | userid | roleid |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
Kelas PoJo yang sesuai adalah sebagai berikut:
/*** Pengguna*/Pengguna kelas publik {Private Integer ID; nama pengguna string pribadi; kata sandi string pribadi; // Getter & Setter ...} /*** Peran*/Peran kelas publik {Private String ID; Private String Rolename;} /*** Sumber Daya*/Sumber Daya Kelas Publik {Private String ID; Private String Resname;} /*** Role-Resource*/Roleres kelas publik {private string ID; RoleID string pribadi; residor string pribadi;} /*** Pengguna-Rol*/Kelas Publik USERROLE {Private String ID; Private String UserID; Private String RoleIDID;} Untuk langkah -langkah terperinci untuk mengintegrasikan Spring dan Shiro, silakan merujuk ke blog saya "Mengintegrasikan Apache Shiro dalam Aplikasi Musim Semi". Di sini kami menambahkan: Anda perlu memperkenalkan dependensi Shiro terlebih dahulu, buka mvnrepository.com, dan cari Shiro. Kita membutuhkan tiga ketergantungan pertama, yaitu Shiro-Core, Shiro-Web dan Shiro-Spring. Mengambil proyek Maven sebagai contoh, tambahkan dependensi berikut di bawah simpul <dependencies> di pom.xml :
<dependency> <GroupId> org.apache.shiro </groupid> <ArtifactId> shiro-core </arttifactid> <version> 1.4.0 </version> </dependency> <dependency> <groupid> org.apache.shiro </groupid> <ArTifacTid> Shiro-WEB </Art/Version </Version.4.4.4.4.4.4.4.4.4.4.4.4. <groupId> org.apache.shiro </groupid> <ArTifactId> Shiro-Spring </artifactid> <version> 1.4.0 </version> </dependency>
Di application-context.xml Anda perlu mengkonfigurasi kacang shiroFilter seperti ini:
<!-- Configure shiro's filter factory class, id-shiroFilter must be consistent with the filters we configured in web.xml --><bean id="shiroFilter"> <property name="securityManager" ref="securityManager"/> <!-- Login page --> <property name="loginUrl" value="/login"/> <!-- Page after login-successful--> <property Name = "SUCCESTURL" Value = "/Index"/> <!-Akses ilegal ke halaman yang melompat-> <nama properti = "tidak sah" value = "/403"/> <!-Konfigurasi Izin-> <nama properti = "filterchinitions lainnya"> <value> <!-Sumber daya statis yang dapat diakses tanpa authentchinition = – —Encoatic-dan well ecoD-JADI-JADI LAIN-JADI-JADI-JADI-JADI-PERUBAHAN LAIN-JADI-JADI LAIN-BAGAIMAN-DAN PENTING LAIN-BAGAIMAN AUTAS LAIN-PERUBAHAN LAIN-PERUBAHAN LAIN, DAN PENTING LAIN, dan TANPA AUTASI, DAN PENTING LAIN-DAN LAINN. Untuk sumber daya yang diabaikan di atas, semua sumber daya lain perlu diautentikasi sebelum dapat diakses ->/** = authc </ value> </prop Property> </tean>
Selanjutnya, Anda perlu mendefinisikan ranah. Ranah khusus terintegrasi dari kelas AuthorizingRealm :
MyRealm kelas publik memperluas otorisasiRealm {@Autowired private userserverServiceService; / *** Izin Verifikasi*/ @Override Otorisasi yang Dilindungi di DoGetAuthorizationInfo (PrincipalCollection PrincipalCollection) {String LoginName = SecurityUtils.getSubject (). GetPrincipal (). ToString (); if (loginName! = null) {string userid = securityutils.getsubject (). getSession (). getAttribute ("UsersessionId"). ToString (); // Objek Informasi Izin, digunakan untuk menyimpan semua peran dan izin dari pengguna yang ditemukan SimpleauthorizationInfo Info = SimpleAuthorizationInnization baru (); // Koleksi Peran Pengguna Shirouser Shirouser = (Shirouser) PrincipalCollection.getPrimaryPrincipal (); info.setroles (shirouser.getroles ()); info.addstringpermissions (shirouser.getUrlset ()); pengembalian info; } return null; } / ** * Fungsi panggilan balik otentikasi, hubungi * / authenticationInfo doGetAuthenticationInfo (authenticationToken token) {string username = (string) token.getPrincipal (); Pengguna pengguna = pengguna baru (); sysuser.setusername (nama pengguna); coba {list <sysuser> Users = UsserService.FindByNames (pengguna); Daftar <String> roleList = UserserVice.SelectrolenamelistByUserId (Users.get (0) .getId ()); if (users.size ()! = 0) {string pwd = users.get (0) .getPassword (); // Setelah semua verifikasi disahkan, masukkan informasi pengguna di sesi sesi sesi = Securityutils.getSubject (). GetSession (); session.setAttribute ("Usersession", Users.get (0)); session.setAttribute ("UsersessionId", Users.get (0) .getId ()); session.setAttribute ("userroles", org.apache.commons.lang.stringutils.join (rolelist, ",")); return new SimpleAuthenticationInfo (nama pengguna, Users.get (0) .getPassword ()); } else {// pengguna tidak ditemukan melempar baru tidak diketahuicountException (); }} catch (Exception e) {System.out.println (e.getMessage ()); } return null; } /*** Perbarui cache informasi otorisasi pengguna. ? } /*** Perbarui cache informasi pengguna. ? } /*** Hapus cache informasi otorisasi pengguna. ? } /*** Bersihkan cache informasi pengguna. */ public void clearAllCachEdAuthenticationInfo () {getAuthenticationCache (). clear (); } / *** Bersihkan semua cache* / public void clearcache (principalcollection prinsipal) {super.clearcache (prinsipal); } / *** Hapus semua cache otentikasi* / public void clearAllCache () {clearAllCachErticationInfo (); clearallcachedauthorizationInfo (); }}Akhirnya, tentukan pengontrol untuk login pengguna untuk menerima permintaan login pengguna:
@ControllerPublic kelas UserController {/*** Pengguna Login*/@PostMapping ("/Login") Public String Login (@Valid User User, BINDINGRESULT BINDINGRESULT, Redirectattributes redirectattributes) {try {if (bindingResult.Haserrors) () {try {if (bindingResult.haserrors) () {if if (bindingResult } // Gunakan alat izin untuk otentikasi, setelah masuk dengan sukses, lompat ke SuccessUrl yang didefinisikan dalam Shirofilter Bean SecurityUtils.getSubject (). Login (UsernamepasswordToken baru (user.getusername (), user.getpassword ())); return "Redirect: Index"; } catch (authenticationException e) {redirectattributes.addflashattribute ("pesan", "kesalahan pengguna atau kata sandi kesalahan"); return "Redirect: Login"; }}/*** Logout*/@getMapping ("/logout") Public String Logout (redirectAttributes redirectAttributes) {securityutils.getSubject (). LOGOUT (); return "Redirect: Login"; }}Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.