Một trong những vấn đề cần quan tâm khi sử dụng Web Service đó chính là vấn đề bảo mật và quản lý tài khoản truy cập. Do Web Service được đặt trên Web Server, và có thể được truy cập thông qua Internet nên cần phải có cơ chế kiểm soát quyền truy cập và thực hiện. Bài này sẽ giới thiệu một số kỹ thuật sử dụng trong vấn đề bảo mật cho Web Service.
Quản lý tài khoản và phân quyền
ASP.NET cung cấp sẵn chức năng quản lý tài khoản và phân quyền thông qua thư việc System.Web.Security, trong đó lớp Membership quản lý các tài khoản và lớp Roles quản lý quyền và phân quyền. Các tài khoản có thể được tạo ra thông qua các trang quản trị hoặc dùng Web Service. Thông tin về các tài khoản được lưu trong một CSDL SQL Server có tên ASPNETDB.MDF (ngầm định).
Thiết lập quyền truy cập và sử dụng Web Service
Web Service cũng như Web Page, một số cho phép truy cập tự do, một số yêu cầu phải có quyền truy cập. Việc thiết lập quyền truy cập một Web Service được thực hiện như đối với Web Page, và thường được cấu hình trong web.config. Đoạn mã sau thiết lập quyền truy cập Administrators cho tất cả các trang trong thư mục admin:
<location path="Admin"> <system.web> <authorization> <allow roles=”Administrators”/> <deny users=”*”/> </authorization> </system.web> </location>
Tuy nhiên cách thiết lập này thường được áp dụng đối với Web Page, còn đối với Web Service thường cho phép truy cập tự do nhưng thiết lập quyền thực hiện đối với từng phương thức. Để thiết lập quyền thực hiện phương thức, thêm thuộc tính PrincipalPermission và quy định quyền tương ứng.
Đối với những phương thức chỉ yêu cầu đăng nhập, không cần quan tâm đến nhóm, thì đặt Authenticated = true. Ví dụ để thực hiện phương thức GetCategories, chỉ cần đăng nhập thành công:
[WebMethod] [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] public DiscountDataSet.CategoriesDataTable GetCategories() { return new DiscountDataSetTableAdapters.CategoriesTableAdapter().GetData(); }
Các phương thức cần thiết lập các quyền cụ thể, thì ứng với mỗi quyền đặt một thuộc tính PrincipalPermission. Ví dụ để thực hiện phương thức UpdateCategories, cần phải có quyền Administrators hoặc Editors, định nghĩa phương thức đó như sau:
[WebMethod] [PrincipalPermission(SecurityAction.Demand, Role = "Administrators")] [PrincipalPermission(SecurityAction.Demand, Role = "Editors")] public void UpdateCategories(DiscountDataSet.CategoriesDataTable categories) { new DiscountDataSetTableAdapters.CategoriesTableAdapter().Update(categories); }
Để có thể sử dụng các phương thức có thiết lập quyền thực hiện, cần phải đăng nhập với quyền tương ứng. Phương thức đăng nhập có thể được định nghĩa như sau:
[WebMethod] public bool LogIn(string userName, string password) { if (System.Web.Security.Membership.ValidateUser(userName, password)) { FormsAuthentication.SetAuthCookie(userName, true); return true; } else { return false; } }
Ở đây, việc kiểm tra tính hợp lệ của tài khoản được thực hiện bằng phương thức ValidateUser của Membership và đặt trạng thái đăng nhập bằng phương thức SetAuthCookie của FormsAuthentication. Để trạng thái đăng nhập được lưu lại phục vụ cho việc thực hiện các phương thức khác, phía client phải bật Cookie. Phương thức đăng xuất được định nghĩa như sau:
[WebMethod] [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] public void LogOut() { if (Context.User.Identity.IsAuthenticated) FormsAuthentication.SignOut(); }
Sau khi đăng xuất, trạng thái đăng nhập bị xoá và để thực hiện được các phương thức có thiết lập quyền thì phải đăng nhập trở lại.
Để xác định trạng thái đăng nhập hiện thời, hoặc xem tài khoản đăng nhập hiện thời có nằm trong nhóm nào đó hay không, có thể định nghĩa các phương thức sau:
[WebMethod] public bool IsAuthenticated() { return Context.User.Identity.IsAuthenticated; } [WebMethod] public bool IsInRole(string role) { return System.Web.Security.Roles.IsUserInRole(role); }
Bật Cookie phía client
Cookie dùng để lưu thông tin qua các lần gọi phương thức, ví dụ trạng thái đăng nhập. Để bật Cookie, cần phải tạo ra một đối tượng CookieContainer và gán cho thuộc tính CookieContainer của service.
service.CookieContainer = new CookieContainer();