2012-01-10 38 views
18

Vì tài liệu về quy trình này rất mơ hồ và khó hiểu (hoặc cũ), tôi muốn xác minh rằng tôi đã làm đúng và không bỏ sót bất kỳ bước nào.Hình thức hiểu bối cảnh hiểu biết.user.identity

Tôi đang cố tạo hệ thống đăng nhập an toàn, hết hạn khi đóng trình duyệt.

- trong web.config của tôi, tôi có sau -

<authentication mode="Forms"> 
     <forms loginUrl="~/Login.aspx" defaultUrl="Index.aspx" name=".ASPXFORMSAUTH" timeout="100" /> 
    </authentication> 
    <authorization> 
     <allow users="?" /> 
    </authorization> 
    <machineKey decryption="AES" validation="SHA1" validationKey.......... /> 

Vì vậy, tôi có một hình thức đăng nhập với tên người dùng/mật khẩu hộp và nút này:

<asp:Button ID="LoginButton" runat="Server" OnClick="Login_Authenticate" Text="Sign in" /> 

Bên Login_Authenticate tôi làm như sau:

protected void Login_Authenticate(object sender, EventArgs e){ 
string userName = UserName.Text; 
string password = Password.Text; 

bool Authenticated = false; 

// Here's code that makes sure that Username and Password is CORRECT 
if(AuthClass.Authenticate(userName, password)){ 
Authenticated = true; 
} 
// error checking does happen here. 

if (Authenticated) 
{ 
    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(30), rememberUserName, String.Empty, FormsAuthentication.FormsCookiePath); 
    string encryptedCookie = FormsAuthentication.Encrypt(ticket); 
    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie); 
    cookie.Expires = DateTime.Now.AddMinutes(30); 
    Response.Cookies.Add(cookie); 
    //FormsAuthentication.RedirectFromLoginPage(userName, false); 

    Response.Redirect("MainPage.aspx"); 
} 
} 

--- trong MasterPage.master.cs Tôi có kiểm tra sau Page_Init () ---

if (Context.User.Identity.IsAuthenticated) 
    { 
     int userid = (int)Session["userid"]; 
     if (userid == null) 
     { 
     userid = GetUserID(Context.User.Identity.Name); 
     if (userid != null) 
     { 
      Session["userid"] = userid; 
     } 
     } 
    } 

EDIT: --- Global.asax; một số mã rằng tôi không hoàn toàn chắc chắn là đúng hay biết những gì nó làm

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
    { 
     // look if any security information exists for this request 
     if (HttpContext.Current.User != null) 
     { 
      // see if this user is authenticated, any authenticated cookie (ticket) exists for this user 
      if (HttpContext.Current.User.Identity.IsAuthenticated) 
      { 
       // see if the authentication is done using FormsAuthentication 
       if (HttpContext.Current.User.Identity is FormsIdentity) 
       { 
        // Get the roles stored for this request from the ticket 
        // get the identity of the user 
        FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity; 
        //Get the form authentication ticket of the user 
        FormsAuthenticationTicket ticket = identity.Ticket; 
        //Get the roles stored as UserData into ticket 
        string[] roles = { }; 
        //Create general prrincipal and assign it to current request 

        HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(identity, roles); 
       } 
      } 
     } 
    } 

--- từ đó trở đi, trên mỗi trang, tôi sử dụng userid phiên để thu thập thông tin người dùng và nội dung và đảm bảo người dùng có quyền xác thực và quyền vai trò nhóm.

Điều này có chính xác không? Hay tôi phải giải mã mọi thứ ở đâu đó?

Điều này có đủ để đăng nhập người dùng an toàn không? Hoặc tôi không nên bận tâm với việc xác thực biểu mẫu và tìm cách riêng của mình để tự tạo cookie và tự quản lý?

+0

gì nếu mã thất bại Authenticated luôn trả về true bool Authenticated = false; // Đây là mã đảm bảo rằng Tên người dùng và Mật khẩu được xác thực là đúng; đây là những gì bạn có ở đầu .. nhưng nếu mã không nó không bao giờ đặt xác thực trở lại sai .. – MethodMan

+0

@ DJKRAZE mã không đặt nó thành false nếu có lỗi. Tôi chỉ không bao gồm mã dài để kiểm tra tên người dùng/mật khẩu. Authenticated = true chỉ xảy ra nếu mọi thứ thành công. – Dexter

+0

Đã thêm một số mã khác để làm rõ và bao gồm mã Global.asax tôi đang sử dụng. Tôi không biết liệu nó có hoạt động hay không và tôi khá bối rối. – Dexter

Trả lời

12

Cách mã của bạn được ghi bằng thông tin đăng nhập sẽ vẫn tồn tại trên các phiên trình duyệt. Nó có thể giúp hiểu những điều cơ bản về những gì đang xảy ra.

Đối với cookie sẽ dựa phương pháp xác thực, có thực sự ba hành động:

1) Đăng nhập - xác nhận thông tin của người dùng và tạo ra và lưu trữ cookie trên trình duyệt của họ.

2) Thoát - chỉ đơn giản là loại bỏ các tập tin cookie từ trình duyệt (do hết hạn cookie hoặc xóa nó)

3) mỗi Request Validation (phần đó là là Application_AuthenticateRequest của bạn) - kiểm tra xem một cookie tồn tại và nếu có, hãy nhận danh tính và vai trò của người dùng và đặt HttpContext.Current.User.

Thông thường, mô-đun Xác thực FormsA giấu hầu hết điều này khỏi bạn.Có vẻ như mã của bạn đang cố gắng sử dụng một số yếu tố của FormAuthentication (như FormsAuthenticationTicket và FormsIdentity. Điều này là tốt miễn là bạn có được những gì bạn muốn.

Đăng nhập của bạn_Authenticate method looks fine EXCEPT bạn đang đặt hết hạn vào Điều này sẽ làm cho cookie tồn tại ngay cả khi bạn đóng và mở lại trình duyệt vì đây không phải là hành vi mà bạn muốn, tôi sẽ không đặt hết hạn cookie.Thiết lập này giống như kiểm tra hộp kiểm "nhớ thông tin đăng nhập của tôi"

Mã trong Application_AuthenticateRequest được chạy mỗi lần trang được phân phát từ ứng dụng của bạn.Nó là công việc chính là đặt HttpContext.Current.User.Thông thường, nếu không có người dùng nào được đăng nhập, Người dùng là null hoặc người dùng Ẩn danh. đã đăng nhập, điều này nên đại diện cho người dùng của bạn.

Nếu bạn đang thực hiện ba điều này, thì ở bất cứ đâu trong mã của bạn, bạn có thể tham khảo HttpContext.Current.User để quyết định mức độ thông tin bạn muốn hiển thị. Ví dụ, nếu bạn muốn giới hạn một trang cho các quản trị viên, bạn có thể gọi HttpContext.Current.Users.IsInRole ("Administrators"), và chuyển hướng chúng ra khỏi trang nếu cuộc gọi trả về false.

Hy vọng điều này sẽ hữu ích.

+0

Tôi hiểu. Tôi đã xung đột với bản thân mình về việc có nên sử dụng cookie và vẫn tồn tại hay không hoặc liệu có kết thúc phiên khi trình duyệt đóng hay không. Tôi vẫn không thể quyết định tôi có nên đi bảo vệ hay tiện lợi hay không. --- Vậy mã trong Application_AuthenticateRequest có hoạt động với mọi thứ không? Tôi không phải giải mã hay bất cứ điều gì cookie ở bất cứ nơi nào trong mã của tôi? Bạn có ý nghĩa gì khi ẩn FormsAuthentication, nó ẩn giấu chính xác điều gì và tại sao tôi không nên sử dụng vé FormAuthentication? Tôi không muốn sử dụng các vai trò trong Current.Users vì tôi truy vấn cơ sở dữ liệu cho một hệ thống vai trò rất cụ thể anyway. – Dexter

+0

Vì bạn đang đặt cookie bằng FormsCookieName và bạn đã bật FormsAuthentication, Xác thực biểu mẫu giải mã cookie và đặt HttpContext.Current.User cho bạn trước khi Application_AuthenticateRequest được gọi. Sử dụng vé FormAuthentication là hoàn toàn chấp nhận được. –

+0

Đối với phần cuối cùng, sử dụng Vai trò - hãy nhớ rằng HttpContext.Current.User có sẵn chỉ là về bất cứ nơi nào trong xử lý yêu cầu của bạn. Để tránh nhấn cơ sở dữ liệu cho mọi truy vấn "vai trò", bạn có thể đặt tất cả vai trò cho người dùng trong Application_AuthenticateRequest bằng một cuộc gọi cơ sở dữ liệu. Hãy coi nó là "bộ nhớ cache vai trò theo yêu cầu". –

2

Có một vấn đề trong thẻ uỷ quyền của bạn phải nộp là:

<authorization> 
    <deny users="?" /> 
    <allow users="*" /> 
</authorization> 

vì bạn muốn từ chối người dùng nặc danh. Nếu bạn khắc phục điều này, bạn có thể xóa an toàn tất cả nội dung khỏi trang chính và global.asax - bạn không phải remap biểu mẫu nhận dạng tùy chỉnh của riêng bạn được lưu trữ trong phiên. Đó là sự lãng phí tài nguyên và tôi không nghĩ nó làm tăng sự an toàn cho giải pháp của bạn một cách đáng kể. Bạn có thể dựa vào cookie biểu mẫu.

+0

Tôi hiểu rồi. Nhưng tôi muốn người dùng ẩn danh nhìn thấy, như trang chính để chọn thông tin đăng nhập. Và tôi muốn họ xem một số trang khác. Tôi cũng cần phải sử dụng các công cụ MasterPage vì tôi cần ID người dùng trên mỗi trang, tôi phải kiểm tra xác thực trên MasterPage hoặc cách khác ASP.net sẽ biết những trang nào không cho phép người dùng ẩn danh? Tôi phải đảm bảo rằng người dùng đã đăng nhập trên nhiều trang. (nếu context.identity.IsAuthenticated là một phần của cây lớn nếu/khác, vì vậy có các trường hợp khác). – Dexter

+0

Ngoài ra chuyển hướng của tôi ở cuối không hoạt động ... – Dexter

+0

"Không hoạt động" nghĩa là gì? –

6

Tôi hơi muộn về đề tài này, nhưng đối với những cố gắng để thực hiện thẩm định hình thức trong khi vẫn giữ những điều đơn giản (như tôi đã cố gắng), ở đây các tài liệu mới nhất có liên quan tôi đã tìm thấy trên MSDN: http://msdn.microsoft.com/en-us/library/xdt4thhy(v=vs.100).aspx

Tóm lại, đừng làm rối tung việc cài đặt cookie, kiểm tra chúng, lập tức vé hoặc hiệu trưởng, ... Để lại cho nó FormsAuthentication lớp.

Ngày đăng nhập vào, khi mã của bạn có kiểm tra thông tin và nếu họ có giá trị, chỉ cần gọi

FormsAuthentication.RedirectFromLoginPage(yourUserId, false); 

Nó thiết lập các cookie xác thực cho bạn, trong đó, kết hợp với việc chuyển hướng, là đủ. "false" là không kiên trì ủy quyền: nó sẽ bị mất khi đóng trình duyệt (hoặc thời gian chờ ủy quyền).

Khi yêu cầu đã được xác thực, không có gì để kiểm tra bằng mã để đảm bảo xác thực của bạn hợp lệ. Sử dụng Context.User.Identity.Name để biết ai được kết nối (sẽ là chuỗi yourUserId ở trên).

On logout rõ ràng, gọi

FormsAuthentication.SignOut(); 
FormsAuthentication.RedirectToLoginPage(); 

Và có các hình thức xác thực cấu hình trong web.config.

<system.web> 
    <authentication mode="Forms"> 
    <forms loginUrl="yourLoginPage" defaultUrl="yourDefaultPageAfterLogin"> 
    </forms> 
    </authentication> 
    <authorization> 
    <deny users="?" /> 
    </authorization> 
</system.web> 

Lưu ý rằng cho các ứng dụng MVC phần uỷ quyền cần được loại bỏ từ cấu hình và xử lý với AuthorizeAttribute đăng ký như là một thuộc tính lọc toàn cầu, với việc sử dụng của AllowAnonymousAttribute trên bộ điều khiển hoặc các hành động cần nó. (MVC 4; trước này, nó được yêu cầu để tạo ra các thuộc tính riêng của nó để xử lý điều đó.)

1

Luồng công việc đầy đủ cho Ghi nhớ yêu cầu: 1. Ghi dữ liệu tùy chỉnh vào cookie. 2. Đọc dữ liệu tùy chỉnh đó.

Thậm chí nếu bạn có thể xác thực yêu cầu qua cookie, điều đó không có nghĩa là đối tượng HttpSession có thể tiếp tục cho yêu cầu đó.

http://www.codeproject.com/Articles/779844/Remember-Me

enter image description here

Các vấn đề liên quan