2009-08-31 18 views
5

Trong một ứng dụng ASP.net tôi đang sử dụng một điều khiển đăng nhập với một nhà cung cấp thành viên tùy chỉnh mà tôi đã viết. Điều tôi muốn làm là đặt Thread.CurrentPrincipal thành đối tượng chính của tôi, ngay sau khi người dùng được xác thực.Làm thế nào để thiết lập Thread.CurrentPrincipal để sử dụng trong suốt ứng dụng?

Tôi đang sử dụng setter: Thread.CurrentPrincipal và nó đặt đối tượng chính cho tôi nhưng, trên tất cả các chủ đề hậu quả CurrentPrincipal này được ghi đè bằng giá trị mặc định.

Đây là mã của tôi cho sự kiện Authenticate của điều khiển Login:

protected void Login1_Authenticate(object sender, AuthenticateEventArgs e) 
    { 
     string username = Login1.UserName; 
     string password = Login1.Password; 

     if (Membership.ValidateUser(username, password)) 
     { 
      var login = sender as Login; 
      var phoenixIdentity = new PhoenixIdentity("B", "Forms" , true); 
      var principal = new PhoenixPrincipal(phoenixIdentity); 

      Thread.CurrentPrincipal = principal; 
      AppDomain.CurrentDomain.SetThreadPrincipal(principal); 

      HttpContext.Current.User = principal; 

      e.Authenticated = true; 
     } 
    } 

Ví dụ, hãy tưởng tượng rằng tôi đăng nhập với tên người dùng A, tất cả mọi thứ suôn sẻ ... Validation trôi qua, nhưng tôi hardcode người dùng với tên người dùng B trong đối tượng Identity được đặt thành đối tượng chính mà tôi đặt làm đối tượng CurrentPrincipal.

Khi tôi kiểm tra người dùng nào được đặt thành CurrentPrincipal Danh tính ở cuối phương pháp này, nó nói đó là người dùng B. Nhưng khi tôi tải một trang khác và sau đó kiểm tra xem Mã nhận diện của CurrentPrincipal là gì, nó nói đó là người dùng A.

Vì vậy, làm cách nào để tôi có thể làm cho đối tượng CurrentPrincipal của mình tồn tại lâu dài trên tất cả các chủ đề khác và khi nào điều khiển Đăng nhập này đặt đối tượng CurrentPrincipal của Chủ đề?

+0

Bạn đang làm gì? Bạn có muốn mọi người được xác định là người dùng đăng nhập đầu tiên không? Bạn cần phải hiểu các cơ chế xác thực và ủy quyền ứng dụng web, việc sử dụng cookie, v.v. Bạn không thể đặt một chính cho tất cả các chuỗi ứng dụng nhiều người dùng. –

+0

Tất nhiên là không. Có lẽ tôi đã không thể hiện bản thân mình đủ rõ ràng. – Goran

Trả lời

1

Bạn có thể xử lý FormsAuthentication_OnAuthenticate (người gửi đối tượng, FormsAuthenticationEventArgs e) (trong Global.asax) và đặt CurrentPrincipal tại đây.


void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e) 
{ 
var phoenixIdentity = new PhoenixIdentity("B", "Forms" , true); 
var principal = new PhoenixPrincipal(phoenixIdentity); 
e.User = principal; 
} 
+0

Hãy để tôi làm rõ điều này ... Tôi đang sử dụng Xác thực biểu mẫu, nếu bạn không nhận thấy ... Chỉ là tôi muốn giữ Id người dùng (cùng với một số thông tin người dùng khác) trong đối tượng Identity của Thread .CurrentPrincipal, vì vậy tôi đã triển khai các đối tượng Chính và Định danh của riêng mình và ghi đè phương thức Xác thực của Kiểm soát đăng nhập của xác thực Mẫu. – Goran

+0

Tôi sẽ thử ngay bây giờ ... – Goran

2

Tadas không sai, FormsAuthentication được triển khai chính xác sẽ không gây ra sự cố này.

Trang của bạn có thể truy cập ngay cả khi không đăng nhập, chỉ trong trang đăng nhập, nguyên tắc của chuỗi của bạn được đặt theo cách thủ công, nhưng khi bạn nhấn URL khác, nó chắc chắn không gọi trang đăng nhập của bạn và nhớ mỗi trang tự chạy chủ đề khác nhau. Nếu bạn yêu cầu trang đầu tiên và đặt nguyên tắc chuỗi và bạn yêu cầu trang thứ hai trong cùng một phiên bản trình duyệt, nó có thể hoặc không thể là cùng một chuỗi chính xác.

Đây là cách FormsAuthentication hoạt động,

  1. Nó sẽ kiểm tra nếu Auth Cookie được thiết lập hay không, nó sẽ chỉ đạo dùng đến trang đăng nhập
  2. trang Login phải xác nhận và thiết lập cookie auth, như FormsAuthentication.SetAuthCookie
  3. Trước mỗi lần truy cập trang, Bước 1 được thực thi.
  4. Sau khi xác thực thành công Cookie xác thực, ASP.NET đặt nội bộ người dùng hiện tại và tất cả các tham số differnet theo thành phần thành viên của bạn.
  5. Tệp ASP.NET Global.asax có thể cung cấp cho bạn một số sự kiện trong đó bạn có thể thêm mã để kiểm tra ngay sau khi xác thực thành công bạn có thể thay đổi người dùng hiện tại của mình, nhớ đặt nguyên tắc hiện tại của bạn trên trang đăng nhập sẽ không giúp được

Chúng tôi gặp sự cố tương tự khi chúng tôi sử dụng phiên để lưu trữ một số thông tin quan trọng, sau khi các phiên xác thực không được xây dựng lại, vì vậy chúng tôi đã viết Mô-đun HTTP và trong phương pháp init, chúng tôi đã đính kèm sự kiện AfterRequestAcquired và trong sự kiện này, bạn có thể viết để khởi tạo tất cả các biến quan trọng của người dùng.

1

Đây là những gì tôi đã làm trong phương pháp FormsAuthentication_OnAuthenticate:

if (FormsAuthentication.CookiesSupported) 
     { 
      if (Request.Cookies[FormsAuthentication.FormsCookieName] != null) 
      { 
       try 
       { 
        FormsAuthenticationTicket ticket = 
         FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value); 

        var myIdentity = new GenericIdentity("B"); 
        var principal = new GenericPrincipal(myIdentity, new string[]{"rola1"}); 
        e.User = principal; 
       } 
       catch (Exception ex) 
       { 
        // Decrypt method failed. 
       } 
      } 
     } 
     else 
     { 
      throw new HttpException("Cookieless Forms Authentication is not " + 
            "supported for this application."); 
     } 

có vẻ như nó làm việc gì nó phải làm ... Chỉ là nếu tôi đặt cặp chính/bản sắc tùy chỉnh của tôi như e.User, sau đó Tôi có vấn đề serialization mà tôi cần phải sửa tiếp theo ... Cảm ơn các bạn ...

+0

Sự cố serialization đã biến mất khi tôi chuyển sang IIS thay vì sử dụng máy chủ Visual Studio Development. – Goran