Nguyên lý Security
Xây dựng security cho một ứng dụng phần mềm gần như là một yêu cầu bắt buộc đối với tất cả các hệ thống phần mềm. Phân hệ security này có hai nhiệm vụ chính: a) kiểm tra xem người dùng đăng nhập có cung cấp đúng username và password không b) nếu đúng thì kiểm tra người dùng đã đăng nhập có quyền cập nhật, xóa hoặc xem một tài nguyên (địa chỉ url, file, phương thức) nào đó hay không. Hai nhiệm vụ này có khi đi kèm với nhau hoặc có khi tách rời nhau. Chúng thường được gọi bằng cặp tên: xác thực người dùng (authentication) và kiểm quyền (authorization). Đối với một ứng dụng web, do được cài đặt trên Internet và có khả năng bị truy cập rộng rãi bởi tất cả mọi người nên yêu cầu Secuirty cho nó càng trở nên bức thiết hơn.
Thông thường, việc xác thực một người dùng sẽ được thực hiện thông qua màn hình Đăng nhập. Khi đó người dùng sẽ cung cấp một cặp tên đăng nhập và mật khẩu. Hệ thống sẽ kiểm tra xem cặp tên đăng nhập/mật khẩu này có tồn tại trong cơ sở dữ liệu (hoặc là quan hệ hoặc là LDAP) để tra về kết quả là đăng nhập thành công hay không. Do mỗi người dùng khác nhau sẽ có các vai trò (roles) và quyền khác nhau (privileges) nên phân hệ security phải có tính năng kiểm quyền xem người dùng có được phép truy cập một tài nguyên nào đó hay không.
Cách dễ nhất để hiện thực việc kiểm quyền là dùng một đoạn code if ... else. Trước khi truy xuất vào tài nguyên, đoạn code kiểm quyền sẽ được thực thi xem người dùng đang đăng nhập có quyền trên tài nguyên đó không, nếu có thì cho phép tiếp tục làm, nếu không sẽ báo lỗi hoặc chuyển sang một trang thông báo Truy cập không hợp lệ.
Tự xây dựng một security framework
Servlet mặc dù không còn được ưa chuộng để xây dựng một ứng dụng web nhưng lại chính là nền tảng bên dưới của tất cả các MVC web framework như Struts, JSF, SpringMVC. Ngoài ra, servlet còn cung cấp một tiện ích mạnh mẽ cho việc xây dựng ứng dụng web đó chính là lớp Filter. Hiểu một cách nôm na, filter đóng vai trò như một bộ lọc. Filter cho phép lọc các yêu cầu truy cập web theo một mẫu nào đó, ví dụ như *.jsp, *.action, restrictedarea/*. Một đoạn mã trong filter sẽ được thực thi trước khi yêu cầu truy cập web được thực hiện. Theo thiết kế này, filter có thể giúp hiện thực các tính năng của một security framework như đã mô tả ở trên. Ví dụ như ở đoạn mã trong filter ta có thể làm phối hợp cả hai việc xác thực người dùng và kiểm tra quyền.
Để xây dựng framework này ta cần một AuthorizationFilter. Lớp này hiện thực lớp Filter của Java bằng cách nạp chồng phương thức doFilter như sau:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws ServletException, IOException {
HttpSession session = ((HttpServletRequest) request).getSession(true);
User currentUser = (User) session.getAttribute("user");
if (currentUser == null) {
request.getRequestDispatcher("../error.jsp").forward(request, response);
} else {
// Get relevant URI.
String URI = ((HttpServletRequest) request).getRequestURI();
boolean authorized = AuthorizationManager.isUserAuthorized(currentUser, URI);
if (authorized) {
chain.doFilter(request, response);
} else {
request.getRequestDispatcher("../error.jsp").forward(request, response);
}
}
}
Một lớp AuthorizationManager dùng để kiểm tra quyền của user hiện hành.
public class AuthorizationManager {
public static boolean isUserAuthorized(User user, String url)
{
if (user.getName().equals("admin"))
return true;
else
return false;
}
}
Lớp User chỉ đơn giản bao gồm 2 thuộc tính id và name như sau:
public class User {
private int id;
private String name;
}
Quan trọng nhất ta cần phải kích hoạt filter cho ứng dụng bằng cách cho thêm đoạn code sau vào trong file web.xml:
<filter>
<filter-name>AuthorizationFilterfilter-name>
<filter-class>examples.AuthorizationFilterfilter-class>
filter>
<filter-mapping>
<filter-name>AuthorizationFilterfilter-name>
<url-pattern>/restricted/*url-pattern>
filter-mapping>
Đoạn code này báo cho servlet container biết phải lọc tất cả những request tới thư mục /restricted.
Như vậy, việc xây dựng 1 security framework như Spring Security hoàn toàn khả thi và không có gì quá bí hiểm.
Các framework security chính thống:
Acegi (sau này thành Spring Security) là một framework security cho các ứng dụng web rất nổi tiếng và được ưa chuộng trong cộng đồng lập trình Java. Có nhiều người xem đây như một de facto standard. Acegi hay Spring Security trên thực tế cũng sử dụng Servlet Filter để hiện thực cả hai việc xác thực quyền và kiểm tra quyền. Các web server hoặc application server có cơ chế security riêng thông qua việc sử dụng các realms. Tuy vậy, cách sử dụng security từ các web server trên thực tế không được ưa chuộng vì nó gắn quá chặt với một web server nào đó. Mà điều này thì không có công ty nào muốn.
Download ví dụ này ở đây: MyWeb.zip - 10.1 KB