เมื่อคุณเตรียมที่จะอัพเกรดเว็บแอปพลิเคชันของคุณจาก ASP.NET 1.1 เป็น ASP.NET 2.0 คุณจะประสบปัญหาคุกกี้: คุกกี้ทั้งหมดที่ไคลเอนต์บันทึกในแอปพลิเคชัน ASP.NET 1.1 จะไม่ถูกต้อง
Blog Park ก็ประสบปัญหาดังกล่าวเช่นกัน สำหรับ Blog Park หมายความว่าผู้ใช้ทุกคนที่ใช้คุกกี้จำเป็นต้องเข้าสู่ระบบอีกครั้ง แม้ว่านี่จะไม่ใช่ปัญหาใหญ่ แต่ก็จะนำปัญหามาสู่ทุกคน หากคุณลืมรหัสผ่าน ลำบากมากขึ้น
สำหรับเว็บไซต์ที่ให้ความสำคัญกับความพึงพอใจของผู้ใช้เป็นอย่างมาก ควรมีความพยายามในการแก้ไขปัญหานี้ Blog Park หวังที่จะลดผลกระทบของการอัพเกรดให้มากที่สุดเท่าที่จะเป็นไปได้ ดังนั้นฉันจึงศึกษาปัญหานี้ในช่วงสองวันที่ผ่านมาและพบวิธีแก้ไข
สาเหตุของปัญหาคือ เมื่อโปรแกรมอัพเกรดจาก ASP.NET 1.1 เป็น ASP.NET 2.0 แล้ว ASP.NET 2.0 จะใช้อัลกอริธึมและคีย์ใหม่ในการถอดรหัสคุกกี้ที่ส่งมาจากไคลเอนต์ ซึ่งส่งผลให้ Cookies ไม่ถูกต้อง เอเอสพี.เน็ต 2.0 ใน ASP.NET 1.1 อัลกอริธึม 3DES ถูกใช้เพื่อเข้ารหัสเนื้อหาของคุกกี้ ในขณะที่ ASP.NET 2.0 อัลกอริธึม Advanced Encrypted Standards (AES) ถูกใช้เป็นค่าเริ่มต้นในการถอดรหัส นี่คือหนึ่งในสาเหตุของปัญหา คุณสามารถใช้การตั้งค่าที่เกี่ยวข้องเพื่อเปลี่ยนอัลกอริธึมการเข้ารหัสคุกกี้ใน ASP.NET 2.0 เป็น 3DES เพียงเพิ่ม: <machineKey decryption="3DES"/> ไปที่ web.config แต่หลังจากทำเช่นนี้ ปัญหายังคงมีอยู่ เนื่องจากนอกเหนือจากอัลกอริธึมเดียวกันแล้ว ยังต้องใช้คีย์เดียวกันในการถอดรหัสอีกด้วย หากไม่มีการระบุคีย์ใน machineKey, ASP.NET 2.0 จะใช้คีย์ที่สร้างขึ้นแบบสุ่มโดยค่าเริ่มต้น ค่านี้ผ่านการไตร่ตรอง machineKey ของ ASP.NET 1.1 ถูกตั้งค่าใน machine.config และคีย์สุ่มยังถูกใช้ตามค่าเริ่มต้น:
<machineKey validationKey = "สร้างอัตโนมัติ, IsolateApps" decryptionKey = "สร้างอัตโนมัติ, IsolateApps" การตรวจสอบ = "SHA1"/>
ปัญหาอยู่ที่คีย์สุ่มต่างๆ หากคุณระบุคีย์ใน ASP.NET 1.1 ดั้งเดิม ปัญหานี้จะไม่มีอยู่ แต่โดยทั่วไปจะพิจารณาเมื่อใช้เว็บฟาร์ม โดยปกติแล้วจะใช้คีย์สุ่ม ASP.NET จะสร้างคีย์สุ่มที่แตกต่างกันสำหรับแอปพลิเคชันที่แตกต่างกัน ปัญหาความล้มเหลวของคุกกี้ไคลเอนต์นี้จะเกิดขึ้นในหลาย ๆ สถานการณ์ เช่น: การติดตั้งระบบใหม่ การย้ายแอปพลิเคชัน ASP.NET ไปยังคอมพิวเตอร์เครื่องอื่น แอปพลิเคชันเว็บถูกย้ายไปยังไดเร็กทอรีเสมือนอื่น และอื่น ๆ
วิธีแก้ปัญหานี้?
หลักการนั้นง่ายมาก ตราบใดที่เราทราบค่าของคีย์ที่สร้างขึ้นแบบสุ่มใน ASP.NET 1.1 จากนั้นระบุใน web.config ของแอปพลิเคชัน ASP.NET 2.0 มีสองคีย์ที่นี่: หนึ่งคือการเข้ารหัส คีย์ decryptionKey หนึ่งคือคีย์การคำนวณแฮช validationKey (เพื่อป้องกันไม่ให้คุกกี้ถูกดัดแปลงโดยตรงกลาง) หากเรารู้ว่าคีย์คือ: X และ Y ดังนั้นใน web.config
ปัญหาสามารถแก้ไขได้โดยทำการตั้งค่าต่อไปนี้:
<machineKey validationKey="X" decryptionKey="Y" decryption="3DES"/>
ปัญหาคือวิธีรับค่าของคีย์ที่สร้างแบบสุ่มใน ASP.NET 1.1 รหัสถูกจัดเก็บไว้ใน LSA (หน่วยงานรักษาความปลอดภัยท้องถิ่นของ Windows) แต่ฉันไม่พบวิธีรับรหัสจาก LSA
เนื่องจาก Blog Park แก้ปัญหาคุกกี้การเข้าสู่ระบบเป็นหลัก และคุกกี้นี้ถูกสร้างขึ้นใน System.Web.Security.FormsAuthentication.SetAuthCookie (ชื่อผู้ใช้สตริง, bool createPersistentCookie) ดังนั้นฉันจึงเริ่มจาก System.Web.Security ของ ASP.NET 1.1 เริ่มต้น ด้วยซอร์สโค้ดของ .FormsAuthentication ฉันค้นพบ System.Web.Configuration.MachineKey หลังจากการวิจัยเพิ่มเติมเกี่ยวกับซอร์สโค้ดของ MachineKey ฉันพบสองคีย์ใน MachineKeyConfig ของ MachineKey ซึ่งมีอยู่ในสมาชิกคงที่ส่วนตัวสองตัวของ s_validationKey และ s_oDes ( ต้องใช้ความพยายามอย่างมากในการค้นพบสิ่งนี้) ค่าของ validationKey จะถูกจัดเก็บโดยตรงใน s_validationKey และ decryptionKey จะถูกเก็บไว้ใน s_oDes.Key เนื่องจาก MachineKey เป็นคลาสภายในและ MachineKeyConfig เป็นประเภทส่วนตัว สมาชิกทั้งสองจึงเป็นสมาชิกแบบคงที่ส่วนตัวและไม่สามารถเข้าถึงได้โดยตรง ในเวลานี้ ถึงเวลาที่ฟังก์ชันการสะท้อนอันทรงพลังใน .NET จะเข้ามามีบทบาท ค่าทั้งสองนี้ได้มาจากการสะท้อนกลับ ควรสังเกตว่าประเภทของค่าทั้งสองนี้คือ Byte[] ผ่านการทดสอบพบว่าคีย์ที่สร้างขึ้นโดยการแปลงเป็นสตริงโดยตรงไม่ถูกต้อง คุณต้องเรียก System.Web.Configuration.MachineKey.ByteArrayToHexString ผ่านการสะท้อนกลับ (Byte[], Int32) แปลงเป็นสตริง
ในที่สุดฉันก็แก้ไขปัญหานี้ได้แล้วคืนนี้ ตื่นเต้นมาก! ฉันอยากจะยอมแพ้หลายครั้ง แต่ฉันคิดว่าหลังจากที่โปรแกรม Blog Park ได้รับการอัปเกรดเป็น ASP.NET 2.0 ปัญหานี้อาจสร้างปัญหาให้กับหลายๆ คน แม้ว่าฉันจะต้องเข้าสู่ระบบอีกครั้ง แต่ฉันก็ยังรู้สึกอย่างนั้น ฉันจำเป็นต้องแก้ไขปัญหานี้และการพัฒนาโปรแกรมมีจุดมุ่งหมายเพื่อให้ผู้ใช้ได้รับความสะดวกสบายมากที่สุดไม่ใช่หรือ?
การแก้ปัญหานี้จะเป็นการเตรียมการเพิ่มเติมสำหรับการอัพเกรดเว็บไซต์ Blog Park เป็น ASP.NET 2.0
ที่มา: โปรแกรมเมอร์ dudu-happy