JavaRush /จาวาบล็อก /Random-TH /JAAS - เทคโนโลยีเบื้องต้น (ตอนที่ 2)
Viacheslav
ระดับ

JAAS - เทคโนโลยีเบื้องต้น (ตอนที่ 2)

เผยแพร่ในกลุ่ม
ความต่อเนื่องของส่วนแรกของบทความเกี่ยวกับ JAAS มาดูกันว่าเป็นไปได้หรือไม่ที่จะใช้เฉพาะคำอธิบายประกอบสำหรับ JAAS และเราจะพบปัญหาอะไรบ้าง เราจะเรียนรู้ในส่วนนี้ว่าเครื่องมือ Servlet API ใดที่ช่วยให้เราสร้างโค้ดที่เป็นสากลมากขึ้น และขอสรุปสิ่งที่เราอ่าน
JAAS - เทคโนโลยีเบื้องต้น (ตอนที่ 2) - 1

ความต่อเนื่อง

ในส่วนแรกของการทบทวนเทคโนโลยี JAAS (ดู " JAAS - เทคโนโลยีเบื้องต้น (ตอนที่ 1) ") เราได้พิจารณากรณีการใช้งานหลักสำหรับ JAAS และ Servlet API เราเห็นว่าคอนเทนเนอร์เซิร์ฟเล็ต Tomcat จัดการความปลอดภัยของเว็บแอปพลิเคชันของเราโดยใช้สถาปัตยกรรม JAAS ด้วยความรู้เกี่ยวกับ "วิธีการรับรองความถูกต้อง" และ "ขอบเขตความปลอดภัย" คอนเทนเนอร์ Tomcat เองทำให้เรามีการใช้งานกลไกการตรวจสอบสิทธิ์ที่จำเป็นและมอบ CallbackHandler ให้กับเรา เราเพิ่งใช้มันทั้งหมดในโมดูลการเข้าสู่ระบบของเรา สิ่งสำคัญเพียงอย่างเดียวที่ต้องจำคือเบราว์เซอร์จะบันทึกข้อมูลการเข้าสู่ระบบและรหัสผ่านที่ส่งผ่านการตรวจสอบสิทธิ์ขั้นพื้นฐาน ดังนั้น สำหรับการสแกนใหม่แต่ละครั้งโดยใช้ Chrome คุณสามารถกดCtrl+Shift+Nเพื่อเปิดหน้าต่างใหม่เพื่อทำงานในโหมดไม่ระบุตัวตน
JAAS - เทคโนโลยีเบื้องต้น (ตอนที่ 2) - 2

คำอธิบายประกอบ

การกำหนดค่าโดยใช้ XML ล้าสมัยไปนานแล้ว ดังนั้นจึงเป็นเรื่องสำคัญที่ต้องบอกว่าเริ่มต้นด้วย Servlet API เวอร์ชัน 3.0 เรามีโอกาสที่จะตั้งค่าการตั้งค่าเซิร์ฟเล็ตโดยใช้คำอธิบายประกอบ โดยไม่ต้องใช้ไฟล์ตัวอธิบายการปรับใช้ web.xml มาดูกันว่าการจัดการความปลอดภัยจะเปลี่ยนไปอย่างไรหากเราใช้คำอธิบายประกอบ และเป็นไปได้ไหมที่จะใช้วิธีการที่อธิบายไว้ข้างต้นโดยใช้คำอธิบายประกอบ? ข้อมูลจำเพาะของ Servlet API และส่วน “ คำอธิบายประกอบและความสามารถในการเสียบปลั๊ก ” จะช่วยให้เราเข้าใจคำอธิบายประกอบอีกครั้ง ส่วนนี้บอกว่าการประกาศเซิร์ฟเล็ตweb.xmlสามารถถูกแทนที่ด้วยคำอธิบายประกอบ@WebServletได้ ดังนั้น servlet ของเราจะมีลักษณะดังนี้:
@WebServlet(name="app", urlPatterns = "/secret")
public class App extends HttpServlet {
ต่อไป มาดูบท " 13.3 การรักษาความปลอดภัยทางโปรแกรม " มันบอกว่าเราสามารถประกาศข้อจำกัดด้านความปลอดภัยผ่านคำอธิบายประกอบได้:
@WebServlet(name="app", urlPatterns = "/secret")
@ServletSecurity(httpMethodConstraints = {
        @HttpMethodConstraint(value = "GET", rolesAllowed = "admin")
})
public class App extends HttpServlet {
ตอนนี้web.xmlเหลือเพียงบล็อกเดียวในบ้านของเรา - login-config. ปัญหาคือมันเกิดขึ้นจนไม่มีทางที่จะแทนที่มันได้อย่างง่ายดายและง่ายดาย เนื่องจากการเชื่อมต่อที่ใกล้ชิดระหว่างการตั้งค่าความปลอดภัยของแอปพลิเคชันบนเว็บและการตั้งค่าความปลอดภัยของเว็บเซิร์ฟเวอร์ จึงไม่มีวิธีที่ง่ายและเป็นสากลในการดำเนินการนี้ แม้แต่โดยทางโปรแกรมก็ตาม นี่เป็นหนึ่งในปัญหาของการตรวจสอบสิทธิ์โดยใช้ JAAS และ Servlet API เมื่อพูดถึง block login-configมันก็คุ้มค่าที่จะเข้าใจว่ามันเป็นคำอธิบายที่เปิดเผยของกลไกการรับรองความถูกต้องเช่น กลไกการตรวจสอบสิทธิ์ ยังไม่มีวิธีสากลง่ายๆ ที่จะแทนที่ได้ เพราะ... การประมวลผลweb.xmlเกิดขึ้นลึกภายในคอนเทนเนอร์เซิร์ฟเล็ต ตัวอย่างเช่น ใน Tomcat คุณสามารถดูแหล่งที่มาContextConfig.javaได้ ดังนั้น แม้แต่คอนเทนเนอร์เซิร์ฟเล็ต Tomcat ก็มีหลายตัวเลือกและต่างกันทั้งหมด ตัวอย่างเช่น หากเราใช้คอนเทนเนอร์เซิร์ฟเล็ต Embedded Tomcat (เช่น เราเพิ่มเว็บเซิร์ฟเวอร์จากโค้ด) คุณสามารถอ่านเกี่ยวกับตัวเลือกดังกล่าวได้ที่นี่: “ Embedded Tomcat พร้อมการรับรองความถูกต้องพื้นฐานผ่านโค้ด ” นอกจากนี้ สามารถดูตัวอย่างทั่วไปของการเพิ่ม Embedde Tomcat ได้ในคู่มือแพลตฟอร์ม Heroku PaaS: “ สร้าง Java Web Application โดยใช้ Embedded Tomcat ” หากไม่ได้ใช้ Tomcat ในโหมด Embedded ดังนั้นสำหรับ Tomcat คุณสามารถใช้แนวทางที่ใช้กันทั่วไปได้ - ตัวฟังเหตุการณ์ ใน Tomcat นี่คือ " The LifeCycle Listener Component " ในเวลาเดียวกัน สิ่งสำคัญคือต้องเข้าใจว่าเซิร์ฟเล็ตคอนเทนเนอร์ (ในกรณีของเราคือ Tomcat) อาจมีคลาสโหลดเดอร์เป็นของตัวเอง และคุณไม่สามารถรับและใช้คลาสของคุณได้ สำหรับ Tomcat คุณต้องเข้าใจ " Class Loader HOW-TO " ในคอนเทนเนอร์เซิร์ฟเล็ตอื่นที่เรียกว่า Undertow สามารถทำได้โดยใช้ " Servlet Extensions " อย่างที่คุณเห็น กลไกบางตัวมีกลไกที่ยืดหยุ่นมากกว่า ในขณะที่บางตัวไม่มี อย่างที่คุณเห็นไม่มีทางเลือกเดียว พวกเขาทั้งหมดแตกต่างกันมาก เป็นไปได้ไหมที่จะทำอะไรที่เป็นสากลด้วยเพียง Servlet API และ JAAS เท่านั้น บนอินเทอร์เน็ต คุณสามารถค้นหาข้อเสนอเพื่อใช้ Servlet Filter เพื่อดำเนินการตรวจสอบสิทธิ์โดยไม่มีการlogin-configบล็อก ในที่สุดเรามาพิจารณาตัวเลือกนี้ สิ่งนี้จะทำให้เราสามารถทำซ้ำวิธีการทำงานของ JAAS ได้
JAAS - เทคโนโลยีเบื้องต้น (ตอนที่ 2) - 3

ตัวกรองการรับรองความถูกต้อง

ดังนั้นเป้าหมายของเราคือกำจัดweb.xmlไฟล์ให้หมด หากเรากำจัดมันออกไป น่าเสียดาย เราจะไม่สามารถใช้ข้อจำกัดด้านความปลอดภัยได้อีกต่อไป เนื่องจาก การประมวลผลสามารถเกิดขึ้นได้เร็วกว่าการใช้ตัวกรองเซิร์ฟเล็ตมาก นี่คือค่าธรรมเนียมที่คุณต้องจ่ายสำหรับ "ความสามารถรอบด้าน" ของการใช้ตัวกรอง เหล่านั้น. เราจะต้องลบคำอธิบายประกอบ@ServletSecurityและการตรวจสอบทั้งหมดที่เราอธิบายไว้ก่อนหน้านี้ในข้อจำกัดด้านความปลอดภัยจะต้องดำเนินการโดยทางโปรแกรม อย่างที่คุณเห็น ตัวเลือกนี้ยังกำหนดข้อจำกัดที่ไม่พึงประสงค์หลายประการให้กับเราด้วย ก่อนอื่น เรามาลบคำอธิบายประกอบ@ServletSecurityออกจากทรัพยากรและบล็อกออกlogin-configจากไฟล์web.xml. ตอนนี้เราเองจะต้องดำเนินการรับรองความถูกต้องขั้นพื้นฐาน ตอนนี้เรามาเพิ่มตัวกรองของเรา:
@WebFilter("/*")
public class JaasFilter implements javax.servlet.Filter {
จนถึงตอนนี้มันดูเหมือนง่าย มาเขียนวิธีการเริ่มต้น:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
	String jaas_conf = filterConfig.getServletContext().getRealPath("/WEB-INF/jaas.config");
	System.getProperties().setProperty("java.security.auth.login.config",jaas_conf);
}
อย่างที่คุณเห็น ตอนนี้เราถูกบังคับให้ใช้เครื่องมือ JAAS พื้นฐานเพื่อค้นหาไฟล์กำหนดค่า jaas สิ่งนี้มีข้อเสียเปรียบอย่างมาก - หากมีหลายแอปพลิเคชัน แอปพลิเคชันหนึ่งอาจทำลายการรับรองความถูกต้องของอีกแอปพลิเคชันหนึ่งได้ วิธีการตั้งค่าไฟล์ Jaas Config โดยทั่วไปมีอธิบายโดยละเอียดในเอกสารประกอบ JAAS: " ภาคผนวก A: การตั้งค่า JAAS ในไฟล์คุณสมบัติความปลอดภัย java.security " ต่อไป เราจะอธิบายวิธีการกรองด้วยตัวเอง เริ่มต้นด้วยการรับคำขอ HTTP:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	HttpServletRequest req = (HttpServletRequest) request;
	// Если в реквесте уже есть Principal - ничего не делаем
	if (req.getUserPrincipal() != null ) {
		chain.doFilter(request, response);
	}
ทุกอย่างเรียบง่ายที่นี่ หากมี Principal แสดงว่าการรับรองความถูกต้องสำเร็จ ถัดไป คุณต้องอธิบายการทำงานของตัวกรองเมื่อผู้ใช้ไม่ผ่านการตรวจสอบสิทธิ์ เช่น เขายังไม่ได้รับการจดจำ ก่อนหน้านี้เราได้อธิบายวิธีการรับรองความถูกต้องพื้นฐาน BASIC เพราะ เนื่องจากตอนนี้เรากำลังเขียนตัวกรองเอง เราจึงต้องพิจารณาว่าการตรวจสอบสิทธิ์ขั้นพื้นฐานทำงานอย่างไร คุณสามารถใช้ " เอกสารเว็บ MDN: การอนุญาต HTTP " และ " การตรวจสอบสิทธิ์ HTTP ทำงานอย่างไร " จากคำอธิบายวิธีการทำงานของการตรวจสอบสิทธิ์ขั้นพื้นฐาน ชัดเจนว่าหากเซิร์ฟเวอร์ต้องการดำเนินการตรวจสอบสิทธิ์ BASIC และผู้ใช้ไม่ได้ให้ข้อมูล เซิร์ฟเวอร์จะส่งส่วนหัวพิเศษ "WWW-Authenticate" และรหัสข้อผิดพลาด 401 มาสร้าง วิธีการภายในสำหรับสิ่งนี้:
private void requestNewAuthInResponse(ServletResponse response) throws IOException {
	HttpServletResponse resp = (HttpServletResponse) response;
	String value = "Basic realm=\"JaasLogin\"";
	resp.setHeader("WWW-Authenticate", value);
	resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
ตอนนี้ลองใช้วิธีนี้และเพิ่มdoFilterบล็อกโค้ดต่อไปนี้ให้กับวิธีการ:
// Получаем security Header. А если его нет - запрашиваем
String secHeader = req.getHeader("authorization");
if (secHeader == null) {
	requestNewAuthInResponse(response);
}
ตอนนี้เรามาเพิ่มสาขาสำหรับifซึ่งจะถูกดำเนินการเมื่อมีการส่งส่วนหัวแล้ว:
// Проверяем аутентификацию
else {
	String authorization = secHeader.replace("Basic ", "");
	Base64.Decoder decoder = java.util.Base64.getDecoder();
	authorization = new String(decoder.decode(authorization));
	String[] loginData = authorization.split(":");
	try {
		if (loginData.length == 2) {
			req.login(loginData[0], loginData[1]);
			chain.doFilter(request, response);
		} else {
			requestNewAuthInResponse(response);
		}
	} catch (ServletException e) {
		requestNewAuthInResponse(response);
	}
}
คุณสามารถเพิ่มการอนุญาตให้กับโค้ดนี้ได้ เช่น: req.isUserInRole("admin") ดังนั้นเราจึงได้ทำการตรวจสอบสิทธิ์กับคุณโดยใช้ตัวกรอง ในด้านหนึ่ง มีโค้ดและการประมวลผลแบบแมนนวลจำนวนมาก ในทางกลับกัน มีความคล่องตัวและความเป็นอิสระของเซิร์ฟเวอร์
JAAS - เทคโนโลยีเบื้องต้น (ตอนที่ 2) - 4

บทสรุป

ตอนนี้เรามาถึงจุดสิ้นสุดของการตรวจสอบนี้แล้ว ฉันหวังว่าตอนนี้คงจะชัดเจนขึ้นอีกหน่อยว่า JAAS คืออะไร วิชาคืออะไร และอาจารย์ใหญ่คืออะไร คำว่า Security Realm และ Login Config จะไม่ทำให้เกิดคำถามอีกต่อไป นอกจากนี้ ตอนนี้เรารู้วิธีใช้ JAAS และ Servlet API ร่วมกันแล้ว นอกจากนี้เรายังได้เรียนรู้เกี่ยวกับปัญหาคอขวดที่คำอธิบายประกอบใน Servlet API จะไม่ช่วยเรา แน่นอนว่านี่ไม่ใช่ทั้งหมด ตัวอย่างเช่น การรับรองความถูกต้องใน Java อาจไม่ใช่แค่แบบพื้นฐานเท่านั้น คุณสามารถดูประเภทอื่นๆ ได้ในข้อกำหนด Servlet API ในส่วน " 13.6 การรับรองความถูกต้อง " เป็นการยากที่จะหาข้อมูลโดยละเอียดเกี่ยวกับ JAAS บนอินเทอร์เน็ต แต่ฉันสามารถแนะนำเนื้อหานี้ได้: ฉันหวังว่าข้อมูลจากการตรวจสอบนี้จะเป็นประโยชน์และเข้าใจได้ #เวียเชสลาฟ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION