portaldacalheta.pt
  • หลัก
  • การเพิ่มขึ้นของระยะไกล
  • ผู้คนและทีมงาน
  • การวางแผนและการพยากรณ์
  • การออกแบบ Ux
ส่วนหลัง

REST Security กับ JWT โดยใช้ Java และ Spring Security



ความปลอดภัย

ความปลอดภัยเป็นศัตรูของความสะดวกสบายและในทางกลับกัน คำสั่งนี้เป็นจริงสำหรับระบบใด ๆ ทั้งเสมือนหรือจริงตั้งแต่ทางเข้าบ้านจริงไปจนถึงแพลตฟอร์มเว็บธนาคาร วิศวกรพยายามหาจุดสมดุลที่เหมาะสมสำหรับกรณีการใช้งานที่กำหนดอยู่ตลอดเวลาโดยเอนเอียงไปด้านใดด้านหนึ่ง โดยปกติเมื่อภัยคุกคามใหม่ปรากฏขึ้นเราจะมุ่งไปสู่ความปลอดภัยและไม่สะดวก จากนั้นเราจะดูว่าเราสามารถกู้คืนความสะดวกสบายที่หายไปได้หรือไม่โดยไม่ลดความปลอดภัยมากเกินไป ยิ่งไปกว่านั้นวงจรอุบาทว์นี้ยังคงอยู่ตลอดไป

บทแนะนำการรักษาความปลอดภัยในฤดูใบไม้ผลิ: ภาพประกอบความปลอดภัยเทียบกับความสะดวกสบาย



ความปลอดภัยเป็นศัตรูของความสะดวกสบายและในทางกลับกัน ทวีต

ลองตรวจสอบสถานะของการรักษาความปลอดภัย REST ในวันนี้โดยใช้บทช่วยสอนเกี่ยวกับความปลอดภัยของ Spring ที่ตรงไปตรงมาเพื่อสาธิตการใช้งาน



บริการ REST (ซึ่งย่อมาจาก Representational State Transfer) เริ่มต้นจากวิธีการที่ง่ายมากสำหรับ Web Services ที่มีข้อกำหนดขนาดใหญ่และรูปแบบที่ยุ่งยากเช่น WSDL สำหรับอธิบายบริการหรือ สบู่ สำหรับระบุรูปแบบข้อความ ใน REST เราไม่มีสิ่งเหล่านี้ เราสามารถอธิบายบริการ REST ในไฟล์ข้อความธรรมดาและใช้รูปแบบข้อความที่เราต้องการเช่น JSON, XML หรือแม้แต่ข้อความธรรมดาอีกครั้ง แนวทางที่เรียบง่ายถูกนำไปใช้กับความปลอดภัยของบริการ REST ด้วยเช่นกัน ไม่มีมาตรฐานที่กำหนดไว้กำหนดวิธีการตรวจสอบผู้ใช้โดยเฉพาะ



แม้ว่าบริการ REST จะไม่ได้ระบุไว้มาก แต่สิ่งที่สำคัญคือการขาดสถานะ หมายความว่าเซิร์ฟเวอร์ไม่เก็บสถานะไคลเอ็นต์ใด ๆ โดยมีเซสชันเป็นตัวอย่างที่ดี ดังนั้นเซิร์ฟเวอร์ตอบกลับคำขอแต่ละรายการราวกับว่าเป็นครั้งแรกที่ไคลเอ็นต์ทำ อย่างไรก็ตามแม้ในปัจจุบันการใช้งานจำนวนมากยังคงใช้การรับรองความถูกต้องตามคุกกี้ซึ่งสืบทอดมาจากการออกแบบสถาปัตยกรรมเว็บไซต์มาตรฐาน วิธีการแบบไร้สัญชาติของ REST ทำให้คุกกี้เซสชันไม่เหมาะสมจากจุดยืนด้านความปลอดภัย แต่อย่างไรก็ตามยังคงใช้กันอย่างแพร่หลาย นอกเหนือจากการเพิกเฉยต่อความไร้สัญชาติที่ต้องการแล้วแนวทางที่เรียบง่ายยังมาพร้อมกับการแลกเปลี่ยนความปลอดภัยที่คาดไว้ เมื่อเทียบกับมาตรฐาน WS-Security ที่ใช้สำหรับ Web Services การสร้างและใช้บริการ REST นั้นง่ายกว่ามากดังนั้นความสะดวกสบายจึงผ่านหลังคา การแลกเปลี่ยนมีความปลอดภัยค่อนข้างน้อย การจี้เซสชันและการปลอมแปลงคำขอข้ามไซต์ (XSRF) เป็นปัญหาด้านความปลอดภัยที่พบบ่อยที่สุด

ในการพยายามกำจัดเซสชันไคลเอ็นต์ออกจากเซิร์ฟเวอร์มีการใช้วิธีการอื่น ๆ เป็นครั้งคราวเช่นการตรวจสอบสิทธิ์ HTTP ขั้นพื้นฐานหรือไดเจสต์ ทั้งสองใช้ Authorization ส่วนหัวเพื่อส่งข้อมูลรับรองผู้ใช้โดยเพิ่มการเข้ารหัส (HTTP Basic) หรือการเข้ารหัส (HTTP Digest) แน่นอนว่าพวกเขามีข้อบกพร่องเดียวกันกับที่พบในเว็บไซต์: ต้องใช้ HTTP Basic ผ่าน HTTPS เนื่องจากชื่อผู้ใช้และรหัสผ่านถูกส่งในการเข้ารหัส base64 ที่ย้อนกลับได้อย่างง่ายดายและ HTTP Digest บังคับให้ใช้การแฮช MD5 ที่ล้าสมัยซึ่งพิสูจน์แล้วว่าไม่ปลอดภัย



ในที่สุดการใช้งานบางอย่างก็ใช้โทเค็นโดยพลการเพื่อพิสูจน์ตัวตนลูกค้า ตัวเลือกนี้ดูเหมือนจะดีที่สุดที่เรามีในตอนนี้ หากใช้งานอย่างถูกต้องจะแก้ไขปัญหาด้านความปลอดภัยทั้งหมดของ HTTP Basic, HTTP Digest หรือคุกกี้เซสชันใช้งานง่ายและเป็นไปตามรูปแบบที่ไม่มีสถานะ

อย่างไรก็ตามด้วยโทเค็นตามอำเภอใจดังกล่าวจึงมีมาตรฐานเล็กน้อยที่เกี่ยวข้อง ผู้ให้บริการทุกรายมีความคิดว่าจะใส่อะไรลงในโทเค็นและจะเข้ารหัสหรือเข้ารหัสอย่างไร การใช้บริการจากผู้ให้บริการที่แตกต่างกันจำเป็นต้องใช้เวลาในการตั้งค่าเพิ่มเติมเพื่อปรับให้เข้ากับรูปแบบโทเค็นเฉพาะที่ใช้ ในทางกลับกันวิธีการอื่น ๆ (คุกกี้เซสชัน, HTTP Basic และ HTTP Digest) เป็นที่รู้จักกันดีสำหรับนักพัฒนาและเบราว์เซอร์เกือบทั้งหมดบนอุปกรณ์ทั้งหมดสามารถใช้งานได้ทันที เฟรมเวิร์กและภาษาพร้อมสำหรับวิธีการเหล่านี้โดยมีฟังก์ชันในตัวเพื่อจัดการกับแต่ละส่วนอย่างราบรื่น



การพิสูจน์ตัวตน JWT

JWT (ย่อมาจาก JSON Web Token) คือมาตรฐานที่ขาดหายไปสำหรับการใช้โทเค็นเพื่อพิสูจน์ตัวตนบนเว็บโดยทั่วไปไม่ใช่เฉพาะสำหรับบริการ REST ขณะนี้อยู่ในสถานะร่างเป็น RFC 7519 . มีความแข็งแรงและสามารถรับข้อมูลได้มาก แต่ก็ยังใช้งานง่ายแม้ว่าขนาดจะค่อนข้างเล็กก็ตาม เช่นเดียวกับโทเค็นอื่น ๆ JWT สามารถใช้เพื่อส่งผ่านข้อมูลประจำตัวของผู้ใช้ที่ได้รับการพิสูจน์ตัวตนระหว่างผู้ให้บริการข้อมูลประจำตัวและผู้ให้บริการ (ซึ่งไม่จำเป็นต้องเป็นระบบเดียวกัน) นอกจากนี้ยังสามารถดำเนินการอ้างสิทธิ์ทั้งหมดของผู้ใช้เช่นข้อมูลการให้สิทธิ์ดังนั้นผู้ให้บริการจึงไม่จำเป็นต้องเข้าไปในฐานข้อมูลหรือระบบภายนอกเพื่อตรวจสอบบทบาทและสิทธิ์ของผู้ใช้สำหรับแต่ละคำขอ ข้อมูลนั้นถูกดึงออกจากโทเค็น

นี่คือวิธีการออกแบบความปลอดภัยของ JWT:



ภาพประกอบการไหลของ JWT java

  • ลูกค้าเข้าสู่ระบบโดยส่งข้อมูลประจำตัวไปยังผู้ให้บริการข้อมูลประจำตัว
  • ผู้ให้บริการข้อมูลประจำตัวจะตรวจสอบข้อมูลประจำตัว หากทุกอย่างเรียบร้อยจะดึงข้อมูลผู้ใช้สร้าง JWT ที่มีรายละเอียดผู้ใช้และสิทธิ์ที่จะใช้ในการเข้าถึงบริการและยังกำหนดวันหมดอายุใน JWT (ซึ่งอาจไม่ จำกัด )
  • ผู้ให้บริการข้อมูลประจำตัวจะลงนามและหากจำเป็นให้เข้ารหัส JWT และส่งไปยังไคลเอ็นต์เพื่อตอบสนองต่อคำร้องขอเริ่มต้นด้วยข้อมูลประจำตัว
  • ลูกค้าจัดเก็บ JWT ในระยะเวลาที่ จำกัด หรือไม่ จำกัด ขึ้นอยู่กับการหมดอายุที่กำหนดโดยผู้ให้บริการข้อมูลประจำตัว
  • ไคลเอนต์ส่ง JWT ที่จัดเก็บไว้ในส่วนหัวการอนุญาตสำหรับทุกคำขอไปยังผู้ให้บริการ
  • สำหรับแต่ละคำขอผู้ให้บริการจะใช้ JWT จาก Authorization ส่วนหัวและถอดรหัสหากจำเป็นตรวจสอบลายเซ็นและหากทุกอย่างเรียบร้อยให้แยกข้อมูลผู้ใช้และสิทธิ์ จากข้อมูลนี้เพียงอย่างเดียวและอีกครั้งโดยไม่ต้องค้นหารายละเอียดเพิ่มเติมในฐานข้อมูลหรือติดต่อผู้ให้บริการข้อมูลประจำตัวก็สามารถยอมรับหรือปฏิเสธคำขอของลูกค้าได้ ข้อกำหนดเพียงอย่างเดียวคือข้อมูลประจำตัวและผู้ให้บริการต้องมีข้อตกลงในการเข้ารหัสเพื่อให้บริการสามารถตรวจสอบลายเซ็นหรือแม้แต่ถอดรหัสข้อมูลประจำตัวที่ถูกเข้ารหัส

ขั้นตอนนี้ช่วยให้เกิดความยืดหยุ่นอย่างมากในขณะที่ยังคงรักษาความปลอดภัยและพัฒนาได้ง่าย การใช้วิธีนี้ทำให้ง่ายต่อการเพิ่มโหนดเซิร์ฟเวอร์ใหม่ให้กับคลัสเตอร์ผู้ให้บริการโดยเริ่มต้นด้วยความสามารถในการตรวจสอบลายเซ็นและถอดรหัสโทเค็นโดยให้คีย์ลับที่ใช้ร่วมกันเท่านั้น ไม่จำเป็นต้องมีการจำลองแบบเซสชันการซิงโครไนซ์ฐานข้อมูลหรือการสื่อสารระหว่างโหนด พักผ่อนอย่างเต็มเปี่ยม



ความแตกต่างที่สำคัญระหว่าง JWT และโทเค็นอื่น ๆ โดยพลการคือการกำหนดมาตรฐานของเนื้อหาของโทเค็น อีกวิธีหนึ่งที่แนะนำคือการส่งโทเค็น JWT ใน Authorization ส่วนหัวโดยใช้โครงการ Bearer เนื้อหาของส่วนหัวควรมีลักษณะดังนี้:

วิธีเขียนภาษาโปรแกรม
Authorization: Bearer

การใช้งาน REST Security

เพื่อให้บริการ REST ทำงานได้ตามที่คาดไว้เราจำเป็นต้องใช้วิธีการอนุญาตที่แตกต่างกันเล็กน้อยเมื่อเทียบกับเว็บไซต์แบบหลายหน้าแบบคลาสสิก



แทนที่จะทริกเกอร์กระบวนการพิสูจน์ตัวตนโดยเปลี่ยนเส้นทางไปยังเพจล็อกอินเมื่อไคลเอ็นต์ร้องขอทรัพยากรที่ปลอดภัยเซิร์ฟเวอร์ REST จะพิสูจน์ตัวตนคำขอทั้งหมดโดยใช้ข้อมูลที่มีอยู่ในคำร้องขอโทเค็น JWT ในกรณีนี้ หากการตรวจสอบสิทธิ์ดังกล่าวล้มเหลวการเปลี่ยนเส้นทางก็ไม่สมเหตุสมผล REST API เพียงแค่ส่งการตอบสนองรหัส HTTP 401 (ไม่ได้รับอนุญาต) และลูกค้าควรรู้ว่าต้องทำอย่างไร ตัวอย่างเช่นเบราว์เซอร์จะแสดง div แบบไดนามิกเพื่อให้ผู้ใช้ระบุชื่อผู้ใช้และรหัสผ่าน

ในทางกลับกันหลังจากการรับรองความถูกต้องสำเร็จในเว็บไซต์หลายหน้าแบบคลาสสิกผู้ใช้จะถูกเปลี่ยนเส้นทางโดยใช้รหัส HTTP 301 (ย้ายถาวร) โดยปกติจะไปที่โฮมเพจหรือที่ดีกว่านั้นคือไปยังหน้าที่ผู้ใช้ร้องขอในตอนแรกที่ทริกเกอร์ กระบวนการรับรองความถูกต้อง ด้วย REST อีกครั้งสิ่งนี้ไม่สมเหตุสมผล แต่เราจะดำเนินการตามคำขอต่อไปราวกับว่าทรัพยากรไม่ได้รับความปลอดภัยเลยให้ส่งคืนรหัส HTTP 200 (ตกลง) และเนื้อหาตอบกลับที่คาดไว้

ตัวอย่างการรักษาความปลอดภัยของสปริง

Spring REST Security ด้วย JWT และ Java

ตอนนี้เรามาดูกันว่าเราจะใช้ REST API ที่ใช้โทเค็น JWT ได้อย่างไรโดยใช้ Java และ ฤดูใบไม้ผลิ ในขณะที่พยายามใช้พฤติกรรมเริ่มต้น Spring Security ซ้ำในที่ที่เราทำได้

ตามที่คาดไว้ Spring Security framework มาพร้อมกับคลาสปลั๊กอินที่พร้อมใช้งานจำนวนมากที่จัดการกับกลไกการอนุญาต 'เก่า' ได้แก่ คุกกี้เซสชัน HTTP Basic และ HTTP Digest อย่างไรก็ตามมันขาดการสนับสนุนดั้งเดิมสำหรับ JWT และเราจำเป็นต้องทำให้มือของเราสกปรกเพื่อให้มันใช้งานได้ สำหรับภาพรวมโดยละเอียดเพิ่มเติมคุณควรปรึกษาอย่างเป็นทางการ เอกสาร Spring Security .

มาเริ่มกันเลยตามปกติ นิยามตัวกรอง Spring Security ใน web.xml:

springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy springSecurityFilterChain /*

โปรดทราบว่าชื่อของตัวกรอง Spring Security ต้องตรงกับ springSecurityFilterChain สำหรับส่วนที่เหลือของการกำหนดค่า Spring จะทำงานนอกกรอบ

ต่อไปคือการประกาศ XML ของถั่วสปริงที่เกี่ยวข้องกับความปลอดภัย เพื่อให้ XML ง่ายขึ้นเราจะตั้งค่าเนมสเปซเริ่มต้นเป็น security โดยเพิ่ม xmlns='http://www.springframework.org/schema/security' ไปยังองค์ประกอบราก XML XML ที่เหลือมีลักษณะดังนี้:

(1) (2) (3) (4) (5) (6) (7) (8)
  • (1) ในบรรทัดนี้เราเปิดใช้งาน @PreFilter, @PreAuthorize, @PostFilter, @PostAuthorize คำอธิบายประกอบเกี่ยวกับถั่วสปริงในบริบท
  • (2) เรากำหนดจุดสิ้นสุดการเข้าสู่ระบบและการลงทะเบียนเพื่อข้ามการรักษาความปลอดภัย แม้แต่ 'ไม่เปิดเผยตัวตน' ก็ควรจะดำเนินการสองอย่างนี้ได้
  • (3) ต่อไปเราจะกำหนดห่วงโซ่ตัวกรองที่ใช้กับคำขอทั้งหมดในขณะที่เพิ่มการกำหนดค่าที่สำคัญสองรายการ: การอ้างอิงจุดเริ่มต้นและตั้งค่าการสร้างเซสชันเป็น stateless (เราไม่ต้องการให้เซสชันสร้างขึ้นเพื่อจุดประสงค์ด้านความปลอดภัยเนื่องจากเราใช้โทเค็นสำหรับแต่ละคำขอ)
  • (4) เราไม่ต้องการ csrf การป้องกันเนื่องจากโทเค็นของเรามีภูมิคุ้มกันต่อมัน
  • (5) ต่อไปเราจะเสียบตัวกรองการตรวจสอบความถูกต้องพิเศษของเราภายในห่วงโซ่ตัวกรองที่กำหนดไว้ล่วงหน้าของ Spring ก่อนตัวกรองการเข้าสู่ระบบแบบฟอร์ม
  • (6) ถั่วนี้เป็นการประกาศตัวกรองรับรองความถูกต้องของเรา เนื่องจากกำลังขยาย AbstractAuthenticationProcessingFilter ของ Spring เราจึงจำเป็นต้องประกาศใน XML เพื่อเชื่อมต่อคุณสมบัติของมัน (การต่อสายอัตโนมัติไม่ทำงานที่นี่) เราจะอธิบายในภายหลังว่าตัวกรองทำอะไร
  • (7) ตัวจัดการความสำเร็จเริ่มต้นของ AbstractAuthenticationProcessingFilter ไม่ดีพอสำหรับวัตถุประสงค์ REST เนื่องจากเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าความสำเร็จ นั่นคือเหตุผลที่เราตั้งค่าของเราเองที่นี่
  • (8) คำประกาศของผู้ให้บริการที่สร้างขึ้นโดย authenticationManager ถูกใช้โดยตัวกรองของเราเพื่อตรวจสอบสิทธิ์ผู้ใช้

ตอนนี้เรามาดูกันว่าเราใช้คลาสเฉพาะที่ประกาศใน XML ด้านบนอย่างไร โปรดทราบว่า Spring จะต่อสายให้เรา เราเริ่มต้นด้วยสิ่งที่ง่ายที่สุด

RestAuthenticationEntryPoint.java

public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { // This is invoked when user tries to access a secured REST resource without supplying any credentials // We should just send a 401 Unauthorized response because there is no 'login page' to redirect to response.sendError(HttpServletResponse.SC_UNAUTHORIZED, 'Unauthorized'); } }

ตามที่อธิบายไว้ข้างต้นคลาสนี้จะส่งคืนรหัส HTTP 401 (ไม่ได้รับอนุญาต) เมื่อการตรวจสอบความถูกต้องล้มเหลวซึ่งจะลบล้างการเปลี่ยนเส้นทางเริ่มต้นของ Spring

JwtAuthenticationSuccessHandler.java

public class JwtAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { // We do not need to do anything extra on REST authentication success, because there is no page to redirect to } }

การแทนที่อย่างง่ายนี้จะลบพฤติกรรมเริ่มต้นของการพิสูจน์ตัวตนที่ประสบความสำเร็จ (เปลี่ยนเส้นทางไปที่บ้านหรือหน้าอื่น ๆ ที่ผู้ใช้ร้องขอ) หากคุณสงสัยว่าทำไมเราไม่จำเป็นต้องลบล้าง AuthenticationFailureHandler นั่นเป็นเพราะการใช้งานเริ่มต้นจะไม่เปลี่ยนเส้นทางไปที่ใดก็ได้หากไม่ได้ตั้งค่า URL เปลี่ยนเส้นทางดังนั้นเราจึงหลีกเลี่ยงการตั้งค่า URL ซึ่งดีพอ

JwtAuthenticationFilter.java

public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter { public JwtAuthenticationFilter() { super('/**'); } @Override protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { return true; } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String header = request.getHeader('Authorization'); if (header == null || !header.startsWith('Bearer ')) { throw new JwtTokenMissingException('No JWT token found in request headers'); } String authToken = header.substring(7); JwtAuthenticationToken authRequest = new JwtAuthenticationToken(authToken); return getAuthenticationManager().authenticate(authRequest); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { super.successfulAuthentication(request, response, chain, authResult); // As this authentication is in HTTP header, after success we need to continue the request normally // and return the response as if the resource was not secured at all chain.doFilter(request, response); } }

คลาสนี้เป็นจุดเริ่มต้นของกระบวนการรับรองความถูกต้อง JWT ของเรา ตัวกรองจะแยกโทเค็น JWT ออกจากส่วนหัวของคำร้องขอและมอบหมายการพิสูจน์ตัวตนให้กับการแทรก AuthenticationManager หากไม่พบโทเค็นจะมีข้อยกเว้นที่หยุดการร้องขอจากการประมวลผล นอกจากนี้เรายังต้องการการแทนที่เพื่อให้การตรวจสอบสิทธิ์สำเร็จเนื่องจากการไหลของ Spring เริ่มต้นจะหยุดห่วงโซ่ตัวกรองและดำเนินการเปลี่ยนเส้นทาง โปรดทราบว่าเราจำเป็นต้องใช้สายโซ่เพื่อดำเนินการอย่างเต็มที่รวมถึงการสร้างการตอบสนองตามที่อธิบายไว้ข้างต้น

JwtAuthenticationProvider.java

public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { @Autowired private JwtUtil jwtUtil; @Override public boolean supports(Class authentication) { return (JwtAuthenticationToken.class.isAssignableFrom(authentication)); } @Override protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { } @Override protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) authentication; String token = jwtAuthenticationToken.getToken(); User parsedUser = jwtUtil.parseToken(token); if (parsedUser == null) { throw new JwtTokenMalformedException('JWT token is not valid'); } List authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList(parsedUser.getRole()); return new AuthenticatedUser(parsedUser.getId(), parsedUser.getUsername(), token, authorityList); } }

ในคลาสนี้เราใช้ Spring’s default AuthenticationManager แต่เราฉีดด้วย AuthenticationProvider ของเราเอง นั่นคือกระบวนการรับรองความถูกต้องที่แท้จริง ในการดำเนินการนี้เราขยาย AbstractUserDetailsAuthenticationProvider ซึ่งต้องการให้เราส่งคืน UserDetails เท่านั้น ตามคำขอการตรวจสอบสิทธิ์ในกรณีของเราโทเค็น JWT ที่รวมอยู่ใน JwtAuthenticationToken ชั้นเรียน. หากโทเค็นไม่ถูกต้องเราจะให้ข้อยกเว้น อย่างไรก็ตามหากถูกต้องและถอดรหัสโดย JwtUtil ประสบความสำเร็จเราแยกรายละเอียดผู้ใช้ (เราจะเห็นว่าในคลาส JwtUtil) โดยไม่ต้องเข้าถึงฐานข้อมูลเลย ข้อมูลทั้งหมดเกี่ยวกับผู้ใช้รวมถึงบทบาทของผู้ใช้จะอยู่ในโทเค็นนั้นเอง

วิธีสร้างเว็บไซต์ด้วย angularjs

JwtUtil.java

public class JwtUtil { @Value('${jwt.secret}') private String secret; /** * Tries to parse specified String as a JWT token. If successful, returns User object with username, id and role prefilled (extracted from token). * If unsuccessful (token is invalid or not containing all required user properties), simply returns null. * * @param token the JWT token to parse * @return the User object extracted from specified token or null if a token is invalid. */ public User parseToken(String token) { try { Claims body = Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); User u = new User(); u.setUsername(body.getSubject()); u.setId(Long.parseLong((String) body.get('userId'))); u.setRole((String) body.get('role')); return u; } catch (JwtException | ClassCastException e) { return null; } } /** * Generates a JWT token containing username as subject, and userId and role as additional claims. These properties are taken from the specified * User object. Tokens validity is infinite. * * @param u the user for which the token will be generated * @return the JWT token */ public String generateToken(User u) { Claims claims = Jwts.claims().setSubject(u.getUsername()); claims.put('userId', u.getId() + ''); claims.put('role', u.getRole()); return Jwts.builder() .setClaims(claims) .signWith(SignatureAlgorithm.HS512, secret) .compact(); } }

สุดท้าย JwtUtil คลาสมีหน้าที่แยกวิเคราะห์โทเค็นเป็น User วัตถุและสร้างโทเค็นจาก User วัตถุ. ตรงไปตรงมาเนื่องจากใช้ไฟล์ jjwt ห้องสมุด เพื่อทำงานทั้งหมดของ JWT ในตัวอย่างของเราเราเพียงแค่เก็บชื่อผู้ใช้ ID ผู้ใช้และบทบาทของผู้ใช้ไว้ในโทเค็น นอกจากนี้เรายังสามารถจัดเก็บสิ่งของต่างๆได้ตามอำเภอใจและเพิ่มคุณสมบัติด้านความปลอดภัยอื่น ๆ เช่นการหมดอายุของโทเค็น การแยกวิเคราะห์โทเค็นใช้ใน AuthenticationProvider ดังที่แสดงไว้ด้านบน generateToken() เมธอดถูกเรียกใช้จากบริการ REST เข้าสู่ระบบและสมัครใช้งานซึ่งไม่ปลอดภัยและจะไม่ทริกเกอร์การตรวจสอบความปลอดภัยใด ๆ หรือต้องมีโทเค็นในคำขอ ในท้ายที่สุดมันจะสร้างโทเค็นที่จะถูกส่งกลับไปยังไคลเอนต์ตามผู้ใช้

สรุป

แม้ว่าวิธีการรักษาความปลอดภัยแบบเก่าที่เป็นมาตรฐาน (คุกกี้เซสชัน, HTTP Basic และ HTTP Digest) จะทำงานร่วมกับบริการ REST ได้เช่นกัน แต่ก็มีปัญหาที่ควรหลีกเลี่ยงโดยใช้มาตรฐานที่ดีกว่า JWT มาถึงทันเวลาเพื่อช่วยวันและที่สำคัญที่สุดใกล้จะกลายเป็นมาตรฐาน IETF แล้ว

จุดแข็งหลักของ JWT คือการจัดการการตรวจสอบผู้ใช้แบบไร้สถานะดังนั้นจึงสามารถปรับขนาดได้ในขณะเดียวกันก็รักษาความปลอดภัยด้วยมาตรฐานการเข้ารหัสที่ทันสมัย การจัดเก็บการอ้างสิทธิ์ (บทบาทของผู้ใช้และสิทธิ์) ในโทเค็นนั้นสร้างประโยชน์อย่างมากในสถาปัตยกรรมระบบแบบกระจายซึ่งเซิร์ฟเวอร์ที่ส่งคำขอไม่มีสิทธิ์เข้าถึงแหล่งข้อมูลการพิสูจน์ตัวตน

ทำความเข้าใจพื้นฐาน

REST คืออะไร?

REST ย่อมาจาก Representational State Transfer เป็นรูปแบบสถาปัตยกรรมสำหรับการเปิดเผย API ที่สอดคล้องกันระหว่างบริการบนเว็บ

JWT คืออะไร?

JSON Web Token (JWT) เป็นมาตรฐานสำหรับการเข้ารหัสข้อมูลที่อาจถูกส่งอย่างปลอดภัยเป็นออบเจ็กต์ JSON

Brutalist Web Design, Minimalist Web Design และอนาคตของ Web UX

การออกแบบ Ui

Brutalist Web Design, Minimalist Web Design และอนาคตของ Web UX
การจำลองการตอบสนองและ JSX ใน Vanilla JS

การจำลองการตอบสนองและ JSX ใน Vanilla JS

ส่วนหน้าของเว็บ

โพสต์ยอดนิยม
ความจริงเสมือนในอุตสาหกรรมยานยนต์
ความจริงเสมือนในอุตสาหกรรมยานยนต์
วิธีใช้ Bootstrap และสร้าง. NET Projects
วิธีใช้ Bootstrap และสร้าง. NET Projects
วิธีทำความเข้าใจและประเมินการลงทุนในกองทุนอสังหาริมทรัพย์ส่วนบุคคล
วิธีทำความเข้าใจและประเมินการลงทุนในกองทุนอสังหาริมทรัพย์ส่วนบุคคล
4 ไปวิจารณ์ภาษา
4 ไปวิจารณ์ภาษา
ข้อมูลเบื้องต้นเกี่ยวกับ Magento: การนำทางในระบบนิเวศอีคอมเมิร์ซยอดนิยม
ข้อมูลเบื้องต้นเกี่ยวกับ Magento: การนำทางในระบบนิเวศอีคอมเมิร์ซยอดนิยม
 
วีซ่า H-1B: การเดินทางของนักพัฒนา iOS จากฮอนดูรัสไปยัง Silicon Valley
วีซ่า H-1B: การเดินทางของนักพัฒนา iOS จากฮอนดูรัสไปยัง Silicon Valley
ข้อผิดพลาดทั่วไปในการสื่อสารกับลูกค้า: จะไม่ทำให้ลูกค้าของคุณผิดหวังได้อย่างไร
ข้อผิดพลาดทั่วไปในการสื่อสารกับลูกค้า: จะไม่ทำให้ลูกค้าของคุณผิดหวังได้อย่างไร
การออกแบบที่คาดหวัง: วิธีสร้างประสบการณ์ผู้ใช้ที่มีมนต์ขลัง
การออกแบบที่คาดหวัง: วิธีสร้างประสบการณ์ผู้ใช้ที่มีมนต์ขลัง
กราฟิก 3 มิติ: บทช่วยสอน WebGL
กราฟิก 3 มิติ: บทช่วยสอน WebGL
การออกแบบ VUI - Voice User Interface
การออกแบบ VUI - Voice User Interface
โพสต์ยอดนิยม
  • นักลงทุนที่คาดหวังมักจะสนใจแผนธุรกิจที่แสดงออกมามากที่สุด
  • วิธีการเริ่มต้นกองทุนการค้นหา
  • วิธีทำแก้วกูเกิล
  • การออกแบบกราฟิก vs การออกแบบภาพ
  • ตัวอย่างการส่งแบบฟอร์มเชิงมุม 4
  • วิธีใช้กูเกิลกลาส
หมวดหมู่
  • การเพิ่มขึ้นของระยะไกล
  • ผู้คนและทีมงาน
  • การวางแผนและการพยากรณ์
  • การออกแบบ Ux
  • © 2022 | สงวนลิขสิทธิ์

    portaldacalheta.pt