Shiro
Shiro adalah proyek open source di bawah Apache, kami menyebutnya Apache Shiro. Ini adalah kerangka kerja keamanan yang sangat mudah digunakan dengan proyek Java, memberikan otentikasi, otorisasi, enkripsi, dan manajemen sesi. Seperti keamanan musim semi, ini adalah kerangka kerja keamanan izin. Namun, dibandingkan dengan keamanan musim semi, Shiro menggunakan metode otorisasi yang relatif sederhana, mudah dipahami dan mudah digunakan. Shiro adalah kerangka kerja yang ringan. Ini jauh lebih sederhana daripada keamanan dan tidak rumit keamanan. Untuk perkenalan yang lebih terperinci, pada dasarnya Anda dapat belajar dari situs web resminya (http://shiro.apache.org/) yang terutama menyediakan fungsi -fungsi berikut:
(1) Otentikasi (otentikasi)
(2) Otorisasi (otorisasi)
(3) Manajemen Sesi (Manajemen Sesi)
(4) Kriptografi (enkripsi)
Pertama -tama, layanan otentikasi, yaitu, melalui dia, Anda dapat menyelesaikan otentikasi identitas, memungkinkannya untuk menentukan apakah pengguna adalah anggota nyata.
Kedua, layanan resmi, terus terang, adalah layanan "kontrol akses", yaitu, biarkan dia mengidentifikasi izin apa yang dimiliki pengguna. Terus terang, itu adalah untuk memberinya izin operasi apa dengan menilai peran apa yang pengguna.
Lalu, ada layanan manajemen sesi. Pada saat ini, kerangka kerja manajemen sesi independen berbeda dari sesi HTTP yang kami kenal.
Akhirnya, ia juga menyediakan layanan kriptografi (enkripsi), merangkum banyak algoritma kriptografi.
Hari ini, saya tidak akan mengatakan semua tentang itu, dan fokus pada fungsi manajemen percakapannya. Bahkan, ini adalah sesuatu yang hampir semua jaring harus terlibat.
Sebelum berbicara tentang layanan manajemen sesi Shiro, mari kita tinjau bagaimana kami melakukan manajemen sesi sebelumnya.
1. Pada awalnya kami secara langsung menggunakan mekanisme sesi HTTP dari server web. Artinya, jika pengguna masuk untuk pertama kalinya, wadah web akan membuat sesi untuk permintaan tersebut, dan kemudian menyimpan sesi. Dengan meneruskan sesi yang sesuai sebagai cookie ke klien.
Jika klien mengirimkan permintaan ke server ini lagi, sessionID akan secara otomatis dibawa. Kemudian server web akan menentukan apakah sesi masih dalam memori berdasarkan sessionID yang dibawa oleh klien (sesi memiliki waktu kedaluwarsa dan dapat dikonfigurasi dalam file web.xml). Jika sesi yang sesuai tidak dapat ditemukan, itu berarti bahwa waktu kedaluwarsa sesi telah berlalu. Pada saat ini, server web akan membuat sesi untuk itu lagi, dan kemudian meneruskan sesi baru ke klien seperti sebelumnya.
Oleh karena itu, kami dapat menggunakan mekanisme ini untuk mengelola sesi login pengguna dalam program. Misalnya, setelah login pertama pengguna berhasil, kami menyimpan informasi dasar pengguna di sesi (misalnya: session.setAttribute("user", "userInfo") ). Lain kali pengguna mengunjungi lagi, kami mendapatkan informasi pengguna di sesi saat ini berdasarkan informasi pengguna
( session.getAttribute("user") ) untuk menentukan apakah pengguna telah kedaluwarsa. Jika tidak dapat diperoleh, pengguna akan diminta untuk masuk lagi.
2. Metode kedua adalah mentransfer tempat di mana informasi disimpan ke media pihak ketiga, seperti cache, memecache atau redis. Metode ini terutama diadopsi karena munculnya sistem terdistribusi.
Dalam hal ini, kita perlu menghasilkan sessionid sendiri. Secara umum, kami akan menggunakan awalan yang ditentukan ( user:login:token ) dan tambahkan userid, atau cap waktu. Kemudian kami akan menggunakan sesi ini sebagai kunci cache, dan informasi pengguna sebagai nilai, dan menyimpannya di cache, dan mengatur waktu pembatalan:
jedisclient.set (Tokenkey, jsonutil.tojsonstring (userInfo)); jedisclient.Expire (tokenKey, token_lose_seconds);
Kami juga perlu meneruskan tokenkey yang dihasilkan ke klien melalui cookie: CookieUtils.setCookie(request, response, "TT_TOKEN", tokenKey);
Dengan cara ini, ketika pengguna mengunjungi waktu berikutnya (mendefinisikan pencegat), kita dapat mengambil tokenKey yang sesuai dari cookie, dan kemudian menggunakan tokenKey ini untuk pergi ke cache untuk mengambil nilai yang sesuai. Jika tidak dapat diperoleh, itu berarti bahwa kunci telah kedaluwarsa dan pengguna diminta untuk masuk lagi.
Catatan: Tokenkey penting, itu adalah hub yang menghubungkan sisi cache dan klien.
3. Yang terakhir adalah metode Shiro kami, dan idenya serupa. Kode ini cukup sederhana, jadi saya hanya akan mengunggah kode:
1) Buat file ApplicationContext-Shiro.xml baru:
<? Xml Version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: context = "http://www.springframework.org/scema/www.spramework.org/scema/contpema/www.spramework.org/orgaMema/contpa/context" xmlns: p = "http://www.springframework.org/schema/p" xmlns: aop = "http://www.springframework.org/schema/tx" xmlns: xsi = "http:/schema. XSI: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-weans-4.0.xsd http:/wwww.spramork.orgework.orgemork.orgemork/orgemework.orgemework.orgemework/orgemork.orgemork.orgework.orgemork.orgemork.orgor.orger http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-44 id = "shirofilter"> <name properti = "SecurityManager" Ref = "SecurityManager"> </property> <name properti = "loginUrl" value = "/loginpage"> </property> <properti name = "unkorizedUrl" value = "/pages/unafhorized.jsp"/<name tidak sah = "foliTeT ="/halaman/jouchorized anon </value> </property> </bean> <bean> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"></property> <property name="arguments" ref="securityManager"></property> </bean> <bean id="securityManager"> <property name="cacheManager" ref="cacheManager"></property> <property name="sessionManager" ref="sessionManager"></property> </bean> <bean id="sessionManager"> <property name="sessionDAO" ref="sessionDAO"></bean> //This class needs to be implemented by itself<bean id="cacheManager"></bean></beans>
2) Konfigurasikan filter yang sesuai di web.xml:
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name> shirofilter </filter-name> <rerl-pattern>/*</rerl-pattern> </filter-mapping>
3) Tulis kelas implementasi, mewarisi AbstractSessiondao, dan mengimplementasikan metode yang sesuai.
Paket com.jdd.core.shiro; import com.smart.core.redis.redisManager; impor org.apache.shiro.session.Session; impor org.apache.shiro.Session.unknownSessionException; impor orge.apache.shiro.session.mgt.eis.abstracts; org.springframework.beans.factory.annotation.Autowired; impor org.springframework.util.serializationutils; impor java.io.*; impor java.util.arraylist; impor java.utilection. @Override public void update (sesi sesi) melempar UnknownsessionException {RedisManager.set (SerializationUtils.serialize (session.getId (). ToString ()), Serializationutils.serialize (sesi)); redisManager.Expire (serialisasiutils.serialize (session.getId (). tostring ()), 60); } @Override public void delete (sesi sesi) {redisManager.del (serializationutils.serialize (session.getid (). Tostring ())); } @Override Public Collection <Session> getActivesessions () {return new ArrayList <Session> (); } @Override Dilindungi Serializable Docreate (sesi sesi) {// Ini adalah saat Anda pertama -tama mengakses, membuat Sesializable Serializable sid = this.generateSessionId (sesi); penetapan ditugaskan (sesi, sid); redisManager.set (serialisasiutils.serialize (session.getId (). tostring ()), serializationutils.serialize (sesi)); redisManager.Expire (serialisasiutils.serialize (session.getId (). tostring ()), 60); mengembalikan Sid; } @Override Sesi DoreAdSession (Serializable Serializable) {// Metode ini sebenarnya untuk membaca sesi melalui sessionID. Setiap kali Anda membacanya, waktu kegagalan harus diatur ulang byte [] aa = redisManager.get (serializationutils.serialize (serializable.tostring ())); Sesi sesi = (sesi) serialisasiutils.deserialize (AA); redisManager.set (serialisasiutils.serialize (serializable.tostring ()), serialisasiutils.serialize (sesi)); redisManager.Expire (serialisasiutils.serialize (serializable.tostring ()), 60); sesi kembali; }}4) Langkah selanjutnya adalah mendapatkan sesi Shiro dalam logika setelah login yang berhasil, dan kemudian atur informasi pengguna di
Paket com.smart.controller; impor com.smart.pojo.user; import com.smart.service.userservice; impor org.apache.shiro.securityutils; impor org.apache.shiro.mgt.securityManager; impor org.apache.shiro.subject. org.slf4j.loggerFactory; impor org.springframework.beans.factory.annotation.Autowired; impor org.springframework.steretype.controller; impor org.springframework.ui.model; impor org.springframework.wb javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse;@controller@requestMapping ("/user") kelas publik usercontroller {@Autowired private UserService UserService; @Autowired private SecurityManager SM; // menyuntikkan SecurityManager Private Logger Logger = LoggerFactory.getLogger (usercontroller.class); @RequestMapping (value = "/LoginPage") Public String LoginPage () {return "user/userLogin"; } @RequestMapping (value = "/userLogin", Method = requestMethod.post) Public String UserLogin (@RequestParam (value = "name") nama string, @RequestParam (value = "pwd") string pwd, model model) {logger.info ("enter UserLogin ..."); Pengguna pengguna = UsserService.getUserByNeAndPassword (nama, PWD); if (user == null) {logger.info ("Pengguna tidak ada ..."); model.addattribute ("login_error", "nama pengguna atau kesalahan kata sandi"); return "user/userlogin"; } Securityutils.setsecurityManager (SM); Subjek CurrentUser = SecurityUtils.getSubject (); currentUser.getSession (). setAttribute ("LOGIN_USER", USER); mengembalikan "Redirect:/karyawan/daftar"; }}Dapatkan pengguna saat ini, di Shiro, itu adalah tema, lalu dapatkan sesi yang sesuai, dan atur informasi pengguna di dalamnya. Apakah rasanya agak seperti pengoperasian sesi HTTP? Ha ha.
5) Akhirnya, tentukan Interceptor SpringMVC untuk mendapatkan informasi pengguna di sesi yang sesuai di Interceptor. Jika tidak dapat diperoleh, itu akan melompat ke antarmuka login.
package packer com.smart.core.shiro; import com.smart.pojo.user; import org.apache.shiro.securityutils; import org.apache.shiro.mgt.securitymanager; orger org org.apachecle org.subject; ORTG.SLF4J.LOWGIFORY orgergergerF.subjectry; ORTG.SLF4J.LLF4JI PEMITI PENYIDI; PEMITI PEMITI (PEMITI PEMITI (PEMITI PEMITI (PEMITI PEMITI PRYGLEDEDEDEFORIF (ORTGLEDGLECLEFORIF (ORTGLED LECTERFEOR; org.springframework.beans.factory.annotation.Autowired; impor org.springframework.web.servlet.handlerinteptor; javax.servlet.http.httpservletResponse; kelas publik LoginInterceptor mengimplementasikan handlerInterceptor {private Logger Logger = LoggerFactory.getLogger (LoginInterceptor.class); @Autowired private SecurityManager SM; @Override Public boolean prehandle (httpservletrequest httpservletrequest, httpservletResponse httpservletResponse, objek o) melempar pengecualian {logger.info ("Masukkan LoginInterceptor ..."); Permintaan httpservletRequest = httpservletRequest; Respons httpservletResponse = httpservletResponse; Logger.info ("Minta URI ===>"+request.getRequesturi ()); // Jika itu adalah permintaan untuk halaman login, itu tidak akan dicegat, jika tidak itu akan jatuh ke loop dead if (request.getRequesturi (). Berisi ("LoginPage") || request.getRequesturi (). Berisi ("userLogin")) {return true; } else {Securityutils.setsecurityManager (SM); Subjek CurrentUser = SecurityUtils.getSubject (); Objek obj = currentUser.getSession (). GetAttribute ("login_user"); if (obj == null) {response.sendredirect ("http: // localhost: 8080/user/loginpage"); mengembalikan false; } else {user user = (user) obj; if (user == null || user.getName () == null) {response.sendredirect ("http: // localhost: 8080/user/loginpage"); mengembalikan false; } else {return true; }}}} @Override public void posthandle (httpservletRequest httpservletrequest, httpservletResponse httpservletResponse, objek o, model dan model dan lemparan htqervlets htqervlets htqervexrets (override void afterride void setelah complePetPets) HttpservletResponse httpservletResponse, objek o, pengecualian e) melempar pengecualian {}}Pada dasarnya di sini. Jika Anda mengakses informasi beranda secara langsung sekarang, itu akan secara otomatis melompat ke halaman login.
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.