JavaRush /Blog Java /Random-VI /JAAS - Giới thiệu công nghệ (Phần 1)
Viacheslav
Mức độ

JAAS - Giới thiệu công nghệ (Phần 1)

Xuất bản trong nhóm
Bảo mật truy cập đã được triển khai trong Java từ khá lâu và kiến ​​trúc để cung cấp bảo mật này được gọi là JAAS - Dịch vụ ủy quyền và xác thực Java. Đánh giá này sẽ cố gắng làm sáng tỏ bí ẩn về xác thực, ủy quyền là gì và JAAS phải làm gì với nó. JAAS kết bạn với API Servlet như thế nào và họ gặp vấn đề gì trong mối quan hệ của mình.
JAAS - Giới thiệu công nghệ (Phần 1) - 1

Giới thiệu

Trong bài đánh giá này, tôi muốn thảo luận về một chủ đề như bảo mật ứng dụng web. Java có một số công nghệ cung cấp bảo mật:
  • " Kiến trúc bảo mật nền tảng Java SE ", bạn có thể đọc thêm thông tin chi tiết về kiến ​​trúc này trong Hướng dẫn từ Oracle: " Kiến trúc bảo mật nền tảng JavaTM SE ". Kiến trúc này mô tả cách chúng tôi cần bảo mật các ứng dụng Java của mình trong môi trường thời gian chạy Java SE. Nhưng đây không phải là chủ đề của cuộc trò chuyện của chúng tôi ngày hôm nay.

  • " Kiến trúc mật mã Java " là một phần mở rộng Java mô tả mã hóa dữ liệu. Bạn có thể đọc thêm về tiện ích mở rộng này trên JavaRush trong bài đánh giá " Kiến trúc mật mã Java: Người làm quen đầu tiên " hoặc trong Hướng dẫn từ Oracle: " Hướng dẫn tham khảo Kiến trúc mật mã Java (JCA) ".

Nhưng cuộc trò chuyện của chúng ta hôm nay sẽ nói về một công nghệ khác, được gọi là “Dịch vụ ủy quyền và xác thực Java (JAAS)”. Chính cô ấy là người mô tả những điều quan trọng như xác thực và ủy quyền. Hãy xem xét điều này chi tiết hơn.
JAAS - Giới thiệu công nghệ (Phần 1) - 2

JAAS

JAAS là phần mở rộng của Java SE và được mô tả trong Hướng dẫn tham khảo Dịch vụ xác thực và ủy quyền Java (JAAS) . Đúng như tên gọi của công nghệ, JAAS mô tả cách thực hiện xác thực và ủy quyền:
  • Xác thực ”: Dịch từ tiếng Hy Lạp, “authentikos” có nghĩa là “thực, chính hãng”. Nghĩa là, xác thực là một thử nghiệm về tính xác thực. Rằng bất cứ ai đang được xác thực thực sự là người mà họ nói.

  • Ủy quyền ”: dịch từ tiếng Anh có nghĩa là “sự cho phép”. Nghĩa là, ủy quyền là kiểm soát truy cập được thực hiện sau khi xác thực thành công.

Nghĩa là, JAAS nhằm xác định ai đang yêu cầu quyền truy cập vào tài nguyên và đưa ra quyết định xem liệu người đó có thể có được quyền truy cập này hay không. Một ví dụ nhỏ trong cuộc sống: bạn đang lái xe dọc đường và một thanh tra chặn bạn lại. Vui lòng cung cấp giấy tờ - xác thực. Bạn có thể lái xe với giấy tờ - ủy quyền. Hoặc, ví dụ, bạn muốn mua rượu ở cửa hàng. Đầu tiên, bạn được yêu cầu xuất trình hộ chiếu - xác thực. Tiếp theo, dựa vào độ tuổi của bạn để quyết định xem bạn có đủ điều kiện mua rượu hay không. Đây là sự ủy quyền. Trong các ứng dụng web, đăng nhập với tư cách người dùng (nhập tên người dùng và mật khẩu) là xác thực. Và việc xác định trang nào bạn có thể mở được xác định bằng ủy quyền. Đây là nơi “Dịch vụ xác thực và ủy quyền Java (JAAS)” giúp chúng tôi. Khi xem xét JAAS, điều quan trọng là phải hiểu một số khái niệm chính mà JAAS mô tả: Chủ đề, Nguyên tắc, Chứng chỉ. Chủ đề là chủ đề của xác thực. Tức là nó là người mang hoặc người nắm giữ các quyền. Trong tài liệu, Chủ đề được định nghĩa là nguồn của yêu cầu thực hiện một số hành động. Chủ đề hoặc nguồn phải được mô tả bằng cách nào đó và vì mục đích này, Hiệu trưởng được sử dụng, trong tiếng Nga đôi khi còn được gọi là Hiệu trưởng. Nghĩa là, mỗi Hiệu trưởng là một đại diện cho một Chủ thể theo một quan điểm nhất định. Để rõ ràng hơn, hãy đưa ra một ví dụ: Một người nào đó là Chủ thể. Và những người sau đây có thể đóng vai trò là Hiệu trưởng:
  • bằng lái xe của anh ta đại diện cho một người với tư cách là người tham gia giao thông
  • hộ chiếu của anh ta, như một sự đại diện cho một người với tư cách là một công dân của đất nước anh ta
  • hộ chiếu nước ngoài của mình, như một đại diện của một người với tư cách là người tham gia quan hệ quốc tế
  • thẻ thư viện của anh ấy trong thư viện, như một sự đại diện cho một người như một độc giả gắn bó với thư viện
Ngoài ra, Chủ đề còn có một bộ “Thông tin xác thực”, trong tiếng Anh có nghĩa là “danh tính”. Đây là cách Chủ thể xác nhận rằng anh ta chính là anh ta. Ví dụ: mật khẩu của người dùng có thể là Thông tin xác thực. Hoặc bất kỳ đồ vật nào mà người dùng có thể xác nhận rằng anh ta thực sự là anh ta. Bây giờ chúng ta hãy xem JAAS được sử dụng như thế nào trong các ứng dụng web.
JAAS - Giới thiệu công nghệ (Phần 1) - 3

Ứng dụng web

Vì vậy chúng ta cần một ứng dụng web. Hệ thống xây dựng dự án tự động Gradle sẽ giúp chúng ta tạo ra nó. Nhờ sử dụng Gradle, bằng cách thực thi các lệnh nhỏ, chúng ta có thể tập hợp một dự án Java theo định dạng mà chúng ta cần, tự động tạo cấu trúc thư mục cần thiết và hơn thế nữa. Bạn có thể đọc thêm về Gradle trong phần tổng quan ngắn: " Giới thiệu tóm tắt về Gradle " hoặc trong tài liệu chính thức " Bắt đầu Gradle ". Chúng ta cần khởi tạo dự án (Initialization), và với mục đích này, Gradle có một plugin đặc biệt: “ Gradle Init Plugin ” (Init là viết tắt của Khởi tạo, dễ nhớ). Để sử dụng plugin này, hãy chạy lệnh trên dòng lệnh:
gradle init --type java-application
Sau khi hoàn thành thành công chúng ta sẽ có một dự án Java. Bây giờ chúng ta hãy mở tập lệnh xây dựng của dự án để chỉnh sửa. Tập lệnh xây dựng là một tệp có tên build.gradle, mô tả các sắc thái của quá trình xây dựng ứng dụng. Do đó tên, xây dựng kịch bản. Có thể nói đây là một kịch bản xây dựng dự án. Gradle là một công cụ linh hoạt, các khả năng cơ bản của nó được mở rộng bằng các plugin. Do đó, trước hết, hãy chú ý đến khối “plugin”:
plugins {
    id 'java'
    id 'application'
}
Theo mặc định, Gradle, theo những gì chúng tôi đã chỉ định " --type java-application", đã thiết lập một bộ một số plugin cốt lõi, tức là những plugin đó được bao gồm trong chính bản phân phối của Gradle. Nếu bạn đi tới phần "Tài liệu" (nghĩa là tài liệu) trên trang web gradle.org , thì ở bên trái trong danh sách các chủ đề trong phần "Tham khảo", chúng ta thấy phần " Core Plugins ", tức là. phần mô tả về các plugin rất cơ bản này. Hãy chọn chính xác các plugin mà chúng ta cần chứ không phải những plugin mà Gradle đã tạo cho chúng ta. Theo tài liệu, " Plugin Java Gradle " cung cấp các thao tác cơ bản với mã Java, chẳng hạn như biên dịch mã nguồn. Ngoài ra, theo tài liệu, " plugin ứng dụng Gradle " cung cấp cho chúng ta các công cụ để làm việc với "ứng dụng JVM có thể thực thi", tức là. với một ứng dụng java có thể được khởi chạy dưới dạng một ứng dụng độc lập (ví dụ: ứng dụng bảng điều khiển hoặc ứng dụng có giao diện người dùng riêng). Hóa ra chúng ta không cần plugin “ứng dụng”, bởi vì... chúng tôi không cần một ứng dụng độc lập, chúng tôi cần một ứng dụng web. Hãy xóa nó đi. Cũng như cài đặt “mainClassName”, chỉ có plugin này mới biết. Hơn nữa, trong cùng phần " Đóng gói và phân phối " nơi cung cấp liên kết đến tài liệu Plugin ứng dụng, có một liên kết đến Plugin Gradle War. Plugin Gradle War , như đã nêu trong tài liệu, cung cấp hỗ trợ để tạo các ứng dụng web Java ở định dạng chiến tranh. Ở định dạng WAR có nghĩa là thay vì kho lưu trữ JAR, kho lưu trữ WAR sẽ được tạo. Có vẻ như đây là những gì chúng ta cần. Ngoài ra, như tài liệu cho biết, "Plugin War mở rộng plugin Java". Tức là chúng ta có thể thay thế plugin java bằng plugin war. Do đó, khối plugin của chúng tôi cuối cùng sẽ trông như thế này:
plugins {
    id 'war'
}
Ngoài ra, trong tài liệu về "Plugin chiến tranh Gradle" có nói rằng plugin này sử dụng "Bố cục dự án" bổ sung. Bố cục được dịch từ tiếng Anh là vị trí. Nghĩa là, plugin chiến tranh theo mặc định mong đợi sự tồn tại của một vị trí tệp nhất định mà nó sẽ sử dụng cho các tác vụ của mình. Nó sẽ sử dụng thư mục sau để lưu trữ các tệp ứng dụng web: src/main/webapp Hoạt động của plugin được mô tả như sau:
JAAS - Giới thiệu công nghệ (Phần 1) - 4
Nghĩa là, plugin sẽ tính đến các tệp từ vị trí này khi xây dựng kho lưu trữ WAR cho ứng dụng web của chúng tôi. Ngoài ra, tài liệu về Plugin Gradle War còn nói rằng thư mục này sẽ là "gốc của kho lưu trữ". Và trong đó chúng ta có thể tạo một thư mục WEB-INF và thêm tệp web.xml vào đó. Đây là loại tập tin gì? web.xml- đây là "Bộ mô tả triển khai" hoặc "Bộ mô tả triển khai". Đây là tệp mô tả cách định cấu hình ứng dụng web của chúng tôi để hoạt động. Tệp này chỉ định những yêu cầu mà ứng dụng của chúng tôi sẽ xử lý, cài đặt bảo mật, v.v. Về cốt lõi, nó hơi giống với một tệp kê khai từ tệp JAR (xem " Làm việc với các tệp kê khai: Thông tin cơ bản "). Tệp kê khai cho biết cách làm việc với Ứng dụng Java (tức là kho lưu trữ JAR) và tệp web.xml cho biết cách làm việc với Ứng dụng web Java (tức là kho lưu trữ WAR). Khái niệm "Bộ mô tả triển khai" không tự nó xuất hiện mà được mô tả trong tài liệu " Đặc tả API Servlet"". Bất kỳ ứng dụng web Java nào cũng phụ thuộc vào "API Servlet" này. Điều quan trọng là phải hiểu rằng đây là một API - nghĩa là nó là mô tả của một số hợp đồng tương tác. Ứng dụng web không phải là ứng dụng độc lập. Chúng chạy trên máy chủ web , cung cấp khả năng giao tiếp mạng với người dùng. Nghĩa là, máy chủ web là một loại “vùng chứa" cho các ứng dụng web. Điều này hợp lý, vì chúng tôi muốn viết logic của một ứng dụng web, tức là người dùng sẽ xem những trang nào và như thế nào họ nên phản ứng với hành động của người dùng. Và chúng tôi không muốn viết mã về cách gửi tin nhắn đến người dùng, cách truyền byte thông tin và những thứ khác ở mức độ thấp và đòi hỏi chất lượng rất cao. Ngoài ra, hóa ra các ứng dụng web đều khác nhau, nhưng việc truyền dữ liệu thì giống nhau, tức là hàng triệu lập trình viên sẽ phải viết đi viết lại mã cho cùng một mục đích. Vì vậy, máy chủ web chịu trách nhiệm về một số tương tác của người dùng và trao đổi dữ liệu, ứng dụng web và nhà phát triển chịu trách nhiệm tạo ra dữ liệu đó. Và để kết nối hai phần này, tức là. máy chủ web và ứng dụng web, bạn cần có hợp đồng để tương tác giữa chúng, tức là. họ sẽ tuân theo những quy tắc nào để làm điều này? Để bằng cách nào đó mô tả hợp đồng, sự tương tác giữa ứng dụng web và máy chủ web sẽ như thế nào, API Servlet đã được phát minh. Điều thú vị là ngay cả khi bạn sử dụng các framework như Spring, vẫn có API Servlet chạy ngầm. Tức là bạn sử dụng Spring, Spring làm việc với Servlet API cho bạn. Hóa ra dự án ứng dụng web của chúng ta phải phụ thuộc vào API Servlet. Trong trường hợp này, API Servlet sẽ là một phần phụ thuộc. Như chúng ta đã biết, Gradle cũng cho phép bạn mô tả các phần phụ thuộc của dự án theo cách khai báo. Các plugin mô tả cách quản lý các phần phụ thuộc. Ví dụ: Plugin Java cho Gradle giới thiệu một phương thức quản lý phần phụ thuộc "testImplementation", cho biết rằng phần phụ thuộc đó chỉ cần thiết cho các thử nghiệm. Nhưng Plugin Gradle War bổ sung phương thức quản lý phụ thuộc “providedCompile”, phương thức này cho biết rằng phần phụ thuộc đó sẽ không được đưa vào kho lưu trữ WAR của ứng dụng web của chúng tôi. Tại sao chúng tôi không đưa API Servlet vào kho lưu trữ WAR của mình? Bởi vì Servlet API sẽ được chính máy chủ web cung cấp cho ứng dụng web của chúng ta. Nếu máy chủ web cung cấp API Servlet thì máy chủ đó được gọi là vùng chứa servlet. Do đó, máy chủ web có trách nhiệm cung cấp cho chúng tôi API Servlet và chúng tôi có trách nhiệm chỉ cung cấp ServletAPI tại thời điểm mã được biên dịch. Đó là lý do tại sao providedCompile. Do đó, khối phụ thuộc sẽ trông như thế này:
dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
    testImplementation 'junit:junit:4.12'
}
Vì vậy, chúng ta hãy quay lại tệp web.xml. Theo mặc định, Gradle không tạo bất kỳ Bộ mô tả triển khai nào, vì vậy chúng ta cần tự mình thực hiện việc này. Hãy tạo một thư mục src/main/webapp/WEB-INFvà trong đó chúng ta sẽ tạo một tệp XML có tên web.xml. Bây giờ chúng ta hãy mở chính "Đặc tả Java Servlet" và chương " CHƯƠNG 14 Bộ mô tả triển khai ". Như đã nêu trong "14.3 Bộ mô tả triển khai", tài liệu XML của Bộ mô tả triển khai được mô tả bằng lược đồ http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd . Lược đồ XML mô tả những phần tử mà một tài liệu có thể bao gồm và chúng sẽ xuất hiện theo thứ tự nào. Cái nào là bắt buộc và cái nào không. Nói chung, nó mô tả cấu trúc của tài liệu và cho phép bạn kiểm tra xem tài liệu XML có được soạn thảo chính xác hay không. Bây giờ hãy sử dụng ví dụ từ chương " 14.5 Ví dụ ", nhưng lược đồ phải được chỉ định cho phiên bản 3.1, tức là.
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd
Cái trống của chúng ta web.xmlsẽ trông như thế này:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>JAAS Example</display-name>
</web-app>
Bây giờ hãy mô tả servlet mà chúng ta sẽ bảo vệ bằng JAAS. Trước đây, Gradle đã tạo lớp Ứng dụng cho chúng ta. Hãy biến nó thành một servlet. Như đã nêu trong đặc tả ở " CHƯƠNG 2 Giao diện Servlet ", rằng " Đối với hầu hết các mục đích, Nhà phát triển sẽ mở rộng HttpServlet để triển khai các servlet của họ ", nghĩa là, để biến một lớp thành một servlet, bạn cần kế thừa lớp này từ HttpServlet:
public class App extends HttpServlet {
	public String getGreeting() {
        return "Secret!";
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().print(getGreeting());
    }
}
Như chúng tôi đã nói, API Servlet là một hợp đồng giữa máy chủ và ứng dụng web của chúng tôi. Hợp đồng này cho phép chúng ta mô tả rằng khi người dùng liên hệ với máy chủ, máy chủ sẽ tạo ra một yêu cầu từ người dùng dưới dạng một đối tượng HttpServletRequestvà chuyển nó đến servlet. Nó cũng sẽ cung cấp cho servlet một đối tượng HttpServletResponseđể servlet có thể viết phản hồi cho nó cho người dùng. Khi servlet chạy xong, máy chủ sẽ có thể cung cấp cho người dùng phản hồi dựa trên nó HttpServletResponse. Nghĩa là, servlet không giao tiếp trực tiếp với người dùng mà chỉ với máy chủ. Để máy chủ biết rằng chúng tôi có một servlet và những yêu cầu nào cần sử dụng nó, chúng tôi cần thông báo cho máy chủ về điều này trong bộ mô tả triển khai:
<servlet>
	<servlet-name>app</servlet-name>
	<servlet-class>jaas.App</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>app</servlet-name>
	<url-pattern>/secret</url-pattern>
</servlet-mapping>
Trong trường hợp này, tất cả các yêu cầu /secretsẽ không được gửi đến một servlet của chúng tôi theo tên apptương ứng với lớp jaas.App. Như chúng tôi đã nói trước đó, một ứng dụng web chỉ có thể được triển khai trên máy chủ web. Máy chủ web có thể được cài đặt riêng (độc lập). Nhưng với mục đích của bài đánh giá này, một tùy chọn thay thế sẽ phù hợp - chạy trên máy chủ nhúng. Điều này có nghĩa là máy chủ sẽ được tạo và khởi chạy theo chương trình (plugin sẽ thực hiện việc này cho chúng tôi), đồng thời ứng dụng web của chúng tôi sẽ được triển khai trên đó. Hệ thống xây dựng Gradle cho phép bạn sử dụng plugin " Gradle Gretty Plugin " cho các mục đích sau:
plugins {
    id 'war'
    id 'org.gretty' version '2.2.0'
}
Ngoài ra, plugin Gretty còn có tài liệu hay . Hãy bắt đầu với thực tế là plugin Gretty cho phép bạn chuyển đổi giữa các máy chủ web khác nhau. Điều này được mô tả chi tiết hơn trong tài liệu: " Chuyển đổi giữa các thùng chứa servlet ". Hãy chuyển sang Tomcat, vì... nó là một trong những ứng dụng phổ biến nhất được sử dụng và cũng có tài liệu hay cũng như nhiều ví dụ và vấn đề được phân tích:
gretty {
    // Переключаемся с дефолтного Jetty на Tomcat
    servletContainer = 'tomcat8'
    // Укажем Context Path, он же Context Root
    contextPath = '/jaas'
}
Bây giờ chúng ta có thể chạy "gradle appRun" và sau đó ứng dụng web của chúng ta sẽ có sẵn tại http://localhost:8080/jaas/secret
JAAS - Giới thiệu công nghệ (Phần 1) - 5
Điều quan trọng là phải kiểm tra xem thùng chứa servlet có được Tomcat chọn hay không (xem #1) và kiểm tra xem ứng dụng web của chúng tôi có sẵn ở địa chỉ nào (xem #2).
JAAS - Giới thiệu công nghệ (Phần 1) - 6

Xác thực

Cài đặt xác thực thường bao gồm hai phần: cài đặt ở phía máy chủ và cài đặt ở phía ứng dụng web chạy trên máy chủ này. Cài đặt bảo mật của ứng dụng web không thể tương tác với cài đặt bảo mật của máy chủ web, nếu không vì lý do nào khác ngoài việc ứng dụng web không thể tương tác với máy chủ web. Không phải vô ích khi chúng tôi chuyển sang Tomcat, bởi vì... Tomcat có kiến ​​trúc được mô tả rõ ràng (xem " Kiến trúc Apache Tomcat 8 "). Từ mô tả về kiến ​​trúc này, có thể thấy rõ rằng Tomcat, với tư cách là một máy chủ web, thể hiện ứng dụng web như một bối cảnh nhất định, được gọi là “ Bối cảnh Tomcat ”. Ngữ cảnh này cho phép mỗi ứng dụng web có cài đặt riêng, tách biệt với các ứng dụng web khác. Ngoài ra, ứng dụng web có thể ảnh hưởng đến cài đặt của ngữ cảnh này. Linh hoạt và thuận tiện. Để hiểu sâu hơn, chúng tôi khuyên bạn nên đọc bài viết " Tìm hiểu về Bộ chứa bối cảnh của Tomcat " và phần tài liệu về Tomcat " Bộ chứa bối cảnh ". Như đã nêu ở trên, ứng dụng web của chúng tôi có thể ảnh hưởng đến Bối cảnh Tomcat của ứng dụng bằng cách sử dụng tệp /META-INF/context.xml. Và một trong những cài đặt rất quan trọng mà chúng tôi có thể tác động là Security Realms. Security Realms là một loại “khu vực an ninh”. Một khu vực mà các cài đặt bảo mật cụ thể được chỉ định. Theo đó, khi sử dụng Vương quốc bảo mật, chúng tôi áp dụng các cài đặt bảo mật được xác định cho Vương quốc này. Các lĩnh vực bảo mật được quản lý bởi một vùng chứa, tức là. máy chủ web, không phải ứng dụng web của chúng tôi. Chúng tôi chỉ có thể cho máy chủ biết phạm vi bảo mật nào cần được mở rộng cho ứng dụng của chúng tôi. Tài liệu Tomcat trong phần " Thành phần Vương quốc " mô tả Vương quốc là tập hợp dữ liệu về người dùng và vai trò của họ trong việc thực hiện xác thực. Tomcat cung cấp một tập hợp các triển khai Security Realm khác nhau, một trong số đó là " Jaas Realm ". Đã hiểu một chút thuật ngữ, hãy mô tả Bối cảnh Tomcat trong tệp /META-INF/context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Realm className="org.apache.catalina.realm.JAASRealm"
           appName="JaasLogin"
           userClassNames="jaas.login.UserPrincipal"
           roleClassNames="jaas.login.RolePrincipal"
           configFile="jaas.config" />
</Context>
appName- tên ứng dụng. Tomcat sẽ cố gắng khớp tên này với tên được chỉ định trong tệp configFile. configFile- đây là "tập tin cấu hình đăng nhập". Bạn có thể xem ví dụ về điều này trong tài liệu JAAS: " Phụ lục B: Cấu hình đăng nhập mẫu ". Ngoài ra, điều quan trọng là tệp này sẽ được tìm kiếm đầu tiên trong tài nguyên. Do đó, ứng dụng web của chúng tôi có thể tự cung cấp tệp này. Các thuộc tính userClassNamesroleClassNameschứa dấu hiệu của các lớp đại diện cho hiệu trưởng của người dùng. JAAS tách khái niệm "người dùng" và "vai trò" thành hai khái niệm khác nhau java.security.Principal. Hãy mô tả các lớp trên. Hãy tạo cách triển khai đơn giản nhất cho người dùng chính:
public class UserPrincipal implements Principal {
    private String name;
    public UserPrincipal(String name) {
        this.name = name;
    }
    @Override
    public String getName() {
        return name;
    }
}
Chúng tôi sẽ lặp lại chính xác cách triển khai tương tự cho RolePrincipal. Như bạn có thể thấy từ giao diện, nhiệm vụ chính của Hiệu trưởng là lưu trữ và trả về một số tên (hoặc ID) đại diện cho Hiệu trưởng. Bây giờ, chúng ta có Vương quốc An ninh, chúng ta có các lớp chính. Việc còn lại là điền vào tệp từ configFilethuộc tính " ", hay còn gọi là login configuration file. Mô tả của nó có thể được tìm thấy trong tài liệu Tomcat: " The Realm Component ".
JAAS - Giới thiệu công nghệ (Phần 1) - 7
Nghĩa là, chúng ta có thể đặt cài đặt Cấu hình đăng nhập JAAS vào tài nguyên của ứng dụng web của mình và nhờ vào Bối cảnh Tomcat, chúng ta sẽ có thể sử dụng nó. Tệp này phải có sẵn dưới dạng tài nguyên cho ClassLoader, vì vậy đường dẫn của nó sẽ như sau: \src\main\resources\jaas.config Hãy đặt nội dung của tệp này:
JaasLogin {
    jaas.login.JaasLoginModule required debug=true;
};
Điều đáng chú ý là context.xmltên tương tự được sử dụng ở đây và trong. Điều này ánh xạ Vương quốc bảo mật tới Mô-đun đăng nhập. Vì vậy, Bối cảnh Tomcat đã cho chúng tôi biết lớp nào đại diện cho các lớp chính cũng như lớp nào sẽ được sử dụng. Tất cả những gì chúng ta phải làm là triển khai loginModule này. Đăng nhậpModule có lẽ là một trong những điều thú vị nhất trong JAAS. Tài liệu chính thức sẽ giúp chúng tôi phát triển loginModule: " Dịch vụ ủy quyền và xác thực Java (JAAS): Hướng dẫn dành cho nhà phát triển loginModule ". Hãy thực hiện mô-đun đăng nhập. Hãy tạo một lớp thực hiện giao diện LoginModule:
public class JaasLoginModule implements LoginModule {
}
Đầu tiên chúng ta mô tả phương pháp khởi tạo LoginModule:
private CallbackHandler handler;
private Subject subject;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, <String, ?> sharedState, Map<String, ?> options) {
	handler = callbackHandler;
	this.subject = subject;
}
Phương pháp này sẽ lưu Subject, chúng tôi sẽ xác thực thêm và điền thông tin về các hiệu trưởng. Chúng tôi cũng sẽ tiết kiệm để sử dụng trong tương lai CallbackHandler, số tiền này được trao cho chúng tôi. Với sự trợ giúp, CallbackHandlerchúng tôi có thể yêu cầu nhiều thông tin khác nhau về chủ đề xác thực sau đó. Bạn có thể đọc thêm về nó CallbackHandlertrong phần tương ứng của tài liệu: " Hướng dẫn tham khảo JAAS: CallbackHandler ". Tiếp theo, phương thức loginxác thực được thực thi Subject. Đây là giai đoạn xác thực đầu tiên:
@Override
public boolean login() throws LoginException {
	// Добавляем колбэки
	Callback[] callbacks = new Callback[2];
	callbacks[0] = new NameCallback("login");
	callbacks[1] = new PasswordCallback("password", true);
	// При помощи колбэков получаем через CallbackHandler логин и пароль
	try {
		handler.handle(callbacks);
		String name = ((NameCallback) callbacks[0]).getName();
		String password = String.valueOf(((PasswordCallback) callbacks[1]).getPassword());
		// Далее выполняем валидацию.
		// Тут просто для примера проверяем определённые значения
		if (name != null && name.equals("user123") && password != null && password.equals("pass123")) {
			// Сохраняем информацию, которая будет использована в методе commit
			// Не "пачкаем" Subject, т.к. не факт, что commit выполнится
			// Для примера проставим группы вручную, "хардcodeно".
			login = name;
			userGroups = new ArrayList<String>();
			userGroups.add("admin");
			return true;
		} else {
			throw new LoginException("Authentication failed");
		}
	} catch (IOException | UnsupportedCallbackException e) {
		throw new LoginException(e.getMessage());
	}
}
Điều quan trọng là loginchúng ta không nên thay đổi Subject. Những thay đổi như vậy chỉ xảy ra trong phương thức xác nhận commit. Tiếp theo, chúng ta phải mô tả phương pháp xác nhận xác thực thành công:
@Override
public boolean commit() throws LoginException {
	userPrincipal = new UserPrincipal(login);
	subject.getPrincipals().add(userPrincipal);
	if (userGroups != null && userGroups.size() > 0) {
		for (String groupName : userGroups) {
			rolePrincipal = new RolePrincipal(groupName);
			subject.getPrincipals().add(rolePrincipal);
		}
	}
	return true;
}
Có vẻ lạ khi tách riêng phương thức logincommit. Nhưng vấn đề là các mô-đun đăng nhập có thể được kết hợp. Và để xác thực thành công, có thể cần phải có một số mô-đun đăng nhập hoạt động thành công. Và chỉ khi tất cả các mô-đun cần thiết đã hoạt động thì hãy lưu các thay đổi. Đây là giai đoạn xác thực thứ hai. Hãy kết thúc với abortvà các phương thức logout:
@Override
public boolean abort() throws LoginException {
	return false;
}
@Override
public boolean logout() throws LoginException {
	subject.getPrincipals().remove(userPrincipal);
	subject.getPrincipals().remove(rolePrincipal);
	return true;
}
Phương thức này abortđược gọi khi giai đoạn xác thực đầu tiên không thành công. Phương thức này logoutđược gọi khi hệ thống đăng xuất. Sau khi triển khai Login Modulevà định cấu hình nó Security Realm, Bây giờ chúng tôi cần chỉ ra web.xmlthực tế rằng chúng tôi muốn sử dụng một cái cụ thể Login Config:
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>JaasLogin</realm-name>
</login-config>
Chúng tôi đã chỉ định tên Vương quốc bảo mật của mình và chỉ định Phương thức xác thực - BASIC. Đây là một trong những kiểu xác thực được mô tả trong Servlet API ở phần " 13.6 Authentication ". Còn lại n
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION