2011-09-02 30 views
10

Ok, do đó, điều này có vẻ giống như một nhu cầu chung. Một chút googling tìm thấy rất nhiều cách để làm điều này. Tôi quan tâm đến cách "mvc đúng" nhất để làm điều đó.Cách khởi tạo thông tin về ủy quyền

Tôi có, ở góc trên bên phải của ứng dụng, một lời chào có nội dung là Hello FirstName LastName. Giờ đây, bạn có thể dễ dàng nhận được tên người dùng của người dùng đã đăng nhập, thông qua số IPrincipal (aka User.Identity.Name). Tuy nhiên, điều này sẽ không cho tôi biết họ và tên của người dùng. Tôi phải nhấn API thành viên để có được điều đó.

Nhập API thành viên có những hạn chế của nó. Nó truy cập cơ sở dữ liệu mỗi lần, bổ sung thêm quyền truy cập db vào mỗi trang được phân phối. Thật dễ dàng để đặt một số biến phiên khi đăng nhập, nhưng điều này chỉ hoạt động cho phiên đó. Nếu người dùng nhấp vào "Nhớ thông tin đăng nhập của tôi", thì không có lần đăng nhập nào xảy ra vào lần tiếp theo và tôi vẫn phải tải các giá trị này.

  1. Tôi có thể tạo nhà cung cấp tư cách thành viên của riêng mình để thực hiện một số bộ nhớ đệm, nhưng đó là rất nhiều công việc cho một mục đích đơn lẻ hoặc ít hơn.
  2. Tôi có thể sử dụng Application_AuthenticateRequest và nhấn api thành viên và lưu trữ các giá trị trong biến phiên hoặc tương tự. Điều này là ok, nhưng có vẻ như một chút sức mạnh vũ phu.
  3. Tôi có thể đăng ký bộ lọc chung và xử lý OnAuthenticate, về cơ bản cũng làm như vậy. Điều này có vẻ tốt hơn một chút, nhưng tôi không thích các chi nhánh ở đây.
  4. Tôi có thể lấy được bộ điều khiển cơ sở và mô phỏng thêm các thuộc tính để cung cấp thông tin này. Điều này có vẻ hơi "trường học cũ", và tôi ghét phải làm một lớp cơ sở cho một mục đích duy nhất.
  5. Tôi có thể tạo phương pháp tĩnh bộ nhớ cache để nhận thông tin về quyền truy cập đầu tiên. Điều này về cơ bản không tốt hơn nhiều so với một singleton.
  6. Tôi cũng có thể tạo IPrincipal của riêng mình, nhưng điều đó có nghĩa là truyền nó mỗi lần để lấy dữ liệu, và điều đó có vẻ khó khăn. Tôi có thể bọc nó trong một lớp khác để đơn giản hóa nó, nhưng vẫn ...
  7. Tôi có thể lưu trữ dữ liệu trong cookie xác thực biểu mẫu và lấy nó từ đó. Có một số công cụ có sẵn để làm cho dễ dàng hơn.

Có phương pháp nào mà tôi chưa từng nghĩ đến không? Và cách "mvc đúng" nhất để làm điều đó là gì?

+0

Câu hỏi rất quan trọng đối với tôi quá. –

Trả lời

5

Tôi nghĩ cách tốt nhất là sử dụng Cookie.Đây là giải pháp tôi sử dụng trong my project:

Tạo một lớp để lưu dữ liệu trong nó

[DataContract] 
[Serializable()] 
public class AuthData { 

    [DataMember] 
    public String UserName { get; set; } 

    [DataMember] 
    public String FirstName { get; set; } 

    [DataMember] 
    public String LastName { get; set; } 

    [DataMember] 
    public String Email { get; set; } 

    // any other property you need to a light-store for each user 

    public override string ToString() { 
     string result = ""; 
     try { 
      using (MemoryStream stream = new MemoryStream()) { 
       BinaryFormatter formatter = new BinaryFormatter(); 
       formatter.Serialize(stream, this); 
       result = Convert.ToBase64String(stream.ToArray()); 
      } 
     } catch (Exception ex) { 
      throw new HttpException(ex.Message); 
     } 
     return result; 
    } 

    static public AuthData FromString(String data) { 
     AuthData result = null; 
     try { 
      byte[] array = Convert.FromBase64String(data); 
      using (MemoryStream stream = new MemoryStream(array)) { 
       stream.Seek(0, 0); 
       BinaryFormatter formatter = new BinaryFormatter(); 
       result = (AuthData)formatter.Deserialize(stream, null); 
      } 
     } catch (Exception ex) { 
      throw new HttpException(ex.Message); 
     } 
     return result; 
    } 
} 

| Đăng nhập phương pháp:

public static bool SignIn(string userName, string password, bool persistent){ 
    if (Membership.ValidateUser(userName, password)) { 
     SetAuthCookie(userName, persistent); 
     return true; 
    } 
    return false; 
} 

Setting AuthCookie:

public static void SetAuthCookie(string userName, bool persistent) { 
    AuthData data = GetAuthDataFromDB(); // implement this method to retrieve data from database as an AuthData object 
    var ticket = new FormsAuthenticationTicket(
     1, 
     userName, 
     DateTime.Now, 
     DateTime.Now.Add(FormsAuthentication.Timeout), 
     persistent, 
     data.ToString(), 
     FormsAuthentication.FormsCookiePath 
     ); 
    string hash = FormsAuthentication.Encrypt(ticket); 
    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash); 
    cookie.Expires = DateTime.Now.Add(FormsAuthentication.Timeout); 
    cookie.HttpOnly = false; 
    cookie.Path = FormsAuthentication.FormsCookiePath; 
    HttpContext.Current.Response.Cookies.Add(cookie); 
} 

Bắt AuthCookie:

public static AuthData GetAuthCookie() { 
    if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated && HttpContext.Current.User.Identity is FormsIdentity) { 
     FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; 
     FormsAuthenticationTicket ticket = id.Ticket; 
     var data = AuthData.FromString(ticket.UserData); 
     HttpContext.Current.Items["AuthDataContext"] = data; 
     return data; 
    } 
    return null; 
} 

Trong ControllerBase:

private AuthData _authData; 
private bool _authDataIsChecked; 
public AuthData AuthData { 
    get { 
     _authData = System.Web.HttpContext.Current.Items["AuthDataContext"] as AuthData; 
     if (!_authDataIsChecked && _authData == null) { 
      SignService.GetAuthCookie(); 
      _authData = System.Web.HttpContext.Current.Items["AuthDataContext"] as AuthData; 
      _authDataIsChecked = true; 
     } 
     return _authData; 
    } 
} 
1

Dự án FormsAuthenticationExtensions giải quyết vấn đề này lưu trữ thông tin bổ sung trong chính cookie xác thực. http://formsauthext.codeplex.com/

Điều này phụ thuộc vào lần truy cập cơ sở dữ liệu và tồn tại miễn là cookie xác thực, do đó nó hoạt động nếu người dùng yêu cầu "nhớ tôi". Nó có thể được sử dụng theo cùng một cách (trong MVC) như là các hình thức xác thực tiêu chuẩn.

Đối với câu hỏi của bạn, cách MVCisch nhất là gì: Trước tiên tôi sẽ quyết định nơi tôi muốn giữ thông tin. Phần này của câu hỏi khá độc lập với khung MVC vì các khái niệm (phiên, dữ liệu bài, cookie, vv) được đưa ra có hoặc không có nó.

+0

Có, tôi đã đề cập đến việc sử dụng formsauthext khi tôi đề cập các công cụ để lưu trữ nó trong cookie dễ dàng hơn. –

1

tôi sẽ thực hiện và mở rộng IPrincipalIIdentity, vì vậy khi bạn truy cập User.Identity bạn sẽ tìm thấy LastName và FirstName. Cách này tốt hơn.

Đối với các dự án của tôi, tôi đã mở rộng IIdentity và IPrincipal với các lớp học của tôi thêm các thuộc tính mà tôi luôn cần "ở đó". Đối với tôi không phải là công việc lớn này, ý tôi là, chỉ có một loạt các phương pháp cần được thực hiện.

Đối với IIdentity, yêu cầu giao diện chỉ là AuthenticationType (string), IsAuthenticated (bool)Name (string).

Trong thời gian ở IPrincipal Identity (IIDentity)IsInRole (boolean)

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