Apache Shiro เป็นกรอบความปลอดภัยโอเพนซอร์สที่มีประสิทธิภาพและยืดหยุ่นซึ่งจัดการกระบวนการควบคุมความปลอดภัยที่พบได้ทั่วไปในแอปพลิเคชันระดับองค์กรเช่นการตรวจสอบสิทธิ์การอนุญาตการจัดการเซสชันและการเข้ารหัสในระดับที่ละเอียด เป้าหมายหลักของ Apache Shiro นั้นใช้งานง่ายและเข้าใจได้ บางครั้งการควบคุมกระบวนการรักษาความปลอดภัยอาจมีความซับซ้อนมากซึ่งเป็นอาการปวดหัวสำหรับนักพัฒนา แต่ก็ไม่ได้หมายถึงมัน เฟรมเวิร์กควรปกปิดความซับซ้อนให้มากที่สุดและเปิดเผย API ที่รัดกุมและใช้งานง่ายซึ่งทำให้การทำงานของนักพัฒนาง่ายขึ้นและทำให้มั่นใจในความปลอดภัยของแอปพลิเคชัน เวลานี้เราจะพูดคุยเกี่ยวกับวิธีการใช้ Shiro เพื่อใช้การควบคุมการอนุญาตในแอปพลิเคชันเว็บฤดูใบไม้ผลิ
การทำงาน
Apache Shiro เป็นกรอบความปลอดภัยของแอปพลิเคชันที่ครอบคลุมพร้อมคุณสมบัติมากมาย รูปต่อไปนี้แสดงฟังก์ชั่นที่สำคัญที่สุดใน Shiro:
เป้าหมายหลักของ Shiro คือ "สี่สิ่งสำคัญของแอปพลิเคชันความปลอดภัย" - การตรวจสอบสิทธิ์การอนุญาตการจัดการเซสชันและการเข้ารหัส:
สถาปัตยกรรม
จากมุมมองแบบองค์รวมสถาปัตยกรรมของ Shiro มีสามแนวคิดหลัก: หัวเรื่อง (หัวเรื่องนั่นคือผู้ใช้) ผู้จัดการความปลอดภัย (ผู้จัดการรักษาความปลอดภัย) และอาณาจักร (โดเมน) รูปต่อไปนี้อธิบายถึงความสัมพันธ์ระหว่างส่วนประกอบเหล่านี้:
ส่วนประกอบเหล่านี้สามารถเข้าใจได้ดังนี้:
การเตรียมข้อมูล
ในเว็บแอปพลิเคชันการควบคุมหลักเกี่ยวกับความปลอดภัยคือบทบาททรัพยากรและการอนุญาต (บทบาทใดที่สามารถเข้าถึงทรัพยากรได้) ผู้ใช้สามารถมีหลายบทบาทและบทบาทยังสามารถเข้าถึงทรัพยากรหลายอย่างนั่นคือบทบาทสามารถสอดคล้องกับการอนุญาตหลายอย่าง ในการใช้การออกแบบฐานข้อมูลเราจำเป็นต้องสร้างตารางอย่างน้อย 5 ตาราง: ตารางผู้ใช้ตารางบทบาทตารางทรัพยากรตารางทรัพยากรบทบาทผู้ใช้ตาราง โครงสร้างของ 5 ตารางเหล่านี้มีดังนี้:
ตารางผู้ใช้:
| รหัสประจำตัว | ชื่อผู้ใช้ | รหัสผ่าน |
|---|---|---|
| 1 | จางซาน | 123456 |
| 2 | Li Si | 6666666 |
| 3 | วังวู | 000000 |
รายการบทบาท:
| รหัสประจำตัว | ชื่อ Rolename |
|---|---|
| 1 | ผู้ดูแลระบบ |
| 2 | ผู้จัดการ |
| 3 | พนักงาน |
ตารางทรัพยากร:
| รหัสประจำตัว | ชื่อใหม่ |
|---|---|
| 1 | /ผู้ใช้/เพิ่ม |
| 2 | /ผู้ใช้/ลบ |
| 3 | /Compony/Info |
ตารางทรัพยากรบทบาท:
| รหัสประจำตัว | มีเหตุผล | สิ่งที่เหลืออยู่ |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
ตารางบทบาทผู้ใช้:
| รหัสประจำตัว | ผู้ใช้ | มีเหตุผล |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
คลาส Pojo ที่เกี่ยวข้องมีดังนี้:
/*** ผู้ใช้*/ผู้ใช้ระดับสาธารณะ {ID จำนวนเต็มส่วนตัว; ชื่อผู้ใช้สตริงส่วนตัว; รหัสผ่านสตริงส่วนตัว // getter & setter ... } /*** บทบาท*/บทบาทระดับสาธารณะ {รหัสสตริงส่วนตัว; สตริงส่วนตัว Rolename;} /*** ทรัพยากร*/ทรัพยากรคลาสสาธารณะ {รหัสสตริงส่วนตัว; สตริงส่วนตัว resname;} /*** Role-Resource*/Public Class Roleres {ID สตริงส่วนตัว; สตริงส่วนตัว Roalid; สตริงส่วนตัวตกค้าง;} /*** ระดับผู้ใช้*/คลาสสาธารณะ userrole {รหัสสตริงส่วนตัว; ผู้ใช้สตริงส่วนตัว สตริงส่วนตัว Roilid;} สำหรับขั้นตอนโดยละเอียดเพื่อรวมฤดูใบไม้ผลิและชิโรโปรดดูที่บล็อกของฉัน "การรวม Apache Shiro ในแอปพลิเคชันฤดูใบไม้ผลิ" ที่นี่เราเพิ่ม: คุณต้องแนะนำการพึ่งพาของ Shiro ล่วงหน้าเปิด mvnrepository.com และค้นหา Shiro เราต้องการการพึ่งพาสามครั้งแรกคือ Shiro-Core, Shiro-Web และ Shiro-Spring การใช้โครงการ Maven เป็นตัวอย่างเพิ่มการพึ่งพาต่อไปนี้ภายใต้ <dependencies> โหนดใน pom.xml :
<การพึ่งพา> <roupId> org.apache.shiro </groupId> <ratifactid> Shiro-core </artifactid> <version> 1.4.0 </version> </การพึ่งพาอาศัย> <การพึ่งพา> <roupid> org.apache.shiro </groupid> <ratifactid> <RoupID> org.apache.shiro </groupId> <ratifactid> Shiro-spring </artifactid> <version> 1.4.0 </version>
ใน application-context.xml คุณต้องกำหนดค่าถั่ว shiroFilter เช่นนี้:
<!-กำหนดค่าคลาสโรงงานตัวกรองของ Shiro, id-shirofilter ต้องสอดคล้องกับตัวกรองที่เรากำหนดค่าใน web.xml-> <bean id = "Shirofilter"> <property name = "SecurityManager" ref = "SecurityManager"/> <! name = "successUrl" value = "/index"/> <!-การเข้าถึงหน้ากระโดดที่ผิดกฎหมาย-> <property name = "unauthorizedUrl" value = "/403"/> <! สำหรับทรัพยากรที่ถูกละเว้นข้างต้นทรัพยากรอื่น ๆ ทั้งหมดจะต้องได้รับการรับรองความถูกต้องก่อนที่พวกเขาจะสามารถเข้าถึงได้ ->/** = authc </alue> </porement> </ebean>
ถัดไปคุณต้องกำหนดขอบเขต Custom Realm ถูกรวมเข้าด้วยกันจากคลาส AuthorizingRealm :
ชั้นเรียนสาธารณะ MyRealm ขยาย AuthorizingRealM {@AutoWired Userservice Userservice; / *** อนุญาตการตรวจสอบ*/ @Override Protected AuthorizationInfo DogetAuthorizationInfo (principalcollection principalcollection) {String loginName = SecurityUtils.getSubject (). getPrincipal (). toString (); if (loginName! = null) {string userId = securityUtils.getSubject (). getSession (). getAttribute ("usersessionId"). toString (); // วัตถุข้อมูลการอนุญาตใช้เพื่อจัดเก็บบทบาทและการอนุญาตทั้งหมดของผู้ใช้ที่พบได้ง่ายต่อการกำหนดค่าข้อมูล INFO = ใหม่ SimpleAdeAdizationInfo (); // คอลเลกชันบทบาทผู้ใช้ Shirouser Shirouser = (Shirouser) PrincipalCollection.getPrimaryPrincipal (); info.setroles (Shirouser.getRoles ()); info.addstringpermissions (Shirouser.getUrlset ()); ข้อมูลส่งคืน; } return null; } / ** * ฟังก์ชั่นการโทรกลับการรับรองความถูกต้อง, การโทร * / การรับรองการรับรองความถูกต้องใน doGetAuthenticationInfo (โทเค็น AuthenticationToken) {string username = (String) token.getPrincipal (); ผู้ใช้ผู้ใช้ = ผู้ใช้ใหม่ (); sysuser.setusername (ชื่อผู้ใช้); ลอง {list <sysuser> users = userservice.findbyNames (ผู้ใช้); รายการ <String> ROLELIST = UsersERVICE.SELECTROLENAMELISTBYUSERID (users.get (0) .getId ()); if (users.size ()! = 0) {string pwd = users.get (0) .getPassword (); // หลังจากผ่านการตรวจสอบทั้งหมดให้วางข้อมูลผู้ใช้ในเซสชันเซสชันเซสชัน = SecurityUtils.getSubject (). getSession (); session.setAttribute ("ผู้ใช้", users.get (0)); session.setAttribute ("usersessionId", users.get (0) .getId ()); Session.setAttribute ("Userroles", org.apache.commons.lang.stringutils.join (นักโรลลิสต์, ",")); ส่งคืน SimpleAuthenticationInfo ใหม่ (ชื่อผู้ใช้, users.get (0) .getPassword ()); } else {// ผู้ใช้ไม่พบโยน unknownaccountexception ใหม่ (); }} catch (exception e) {system.out.println (e.getMessage ()); } return null; } /*** อัปเดตแคชข้อมูลการอนุญาตผู้ใช้ */ โมฆะสาธารณะ ClearCachedAuthorizationInfo (หลักการหลักการของผู้อำนวยการ) {super.clearcachedauthorizationInfo (ผู้บริหาร); } /*** อัปเดตแคชข้อมูลผู้ใช้ */ โมฆะสาธารณะ ClearCachedauthenticationInfo (หลักการหลักการของผู้อำนวยการ) {super.clearcachedauthenticationinfo (ผู้บริหาร); } /*** ล้างแคชข้อมูลการอนุญาตของผู้ใช้ */ โมฆะสาธารณะ ClearallCachedAuthorizationInfo () {getAuthorizationCache (). clear (); } /*** ล้างแคชข้อมูลผู้ใช้ */ โมฆะสาธารณะ ClearallcachedauthenticationInfo () {getAuthenticationCache (). clear (); } / *** ล้างแคชทั้งหมด* / โมฆะสาธารณะ ClearCache (principalcollection principals) {super.clearcache (principals); } / *** ล้างแคชการรับรองความถูกต้องทั้งหมด* / โมฆะสาธารณะ ClearallCache () {ClearallCachedAuthenticationInfo (); ClearallcachedauthorizationInfo (); -สุดท้ายกำหนดคอนโทรลเลอร์สำหรับการเข้าสู่ระบบของผู้ใช้เพื่อยอมรับคำขอเข้าสู่ระบบของผู้ใช้:
@ControllerPublic คลาส userController {/*** ผู้ใช้เข้าสู่ระบบ*/@postmapping ("/ล็อกอิน") การเข้าสู่ระบบสตริงสาธารณะ (ผู้ใช้ @valid ผู้ใช้ผู้ใช้, bindingResult bindingResult, redirectattributes redirectattributes) {ลอง {ถ้า } // ใช้เครื่องมือการอนุญาตสำหรับการตรวจสอบความถูกต้องหลังจากเข้าสู่ระบบประสบความสำเร็จให้ข้ามไปที่ SuccessUrl ที่กำหนดไว้ใน Shirofilter Bean SecurityUtils.getSubject (). เข้าสู่ระบบ (ใหม่ผู้ใช้ USERNAMEPASSWORDTOKEN กลับ "เปลี่ยนเส้นทาง: ดัชนี"; } catch (AuthenticationException e) {redirectattributes.addflashattribute ("ข้อความ", "ข้อผิดพลาดชื่อผู้ใช้หรือรหัสผ่าน"); กลับ "เปลี่ยนเส้นทาง: เข้าสู่ระบบ"; }}/*** logout*/@getMapping ("/logout") การออกจากระบบสตริงสาธารณะ (redirectattributes redirectattributes) {securityUtils.getSubject (). logout (); กลับ "เปลี่ยนเส้นทาง: เข้าสู่ระบบ"; -ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น