2009-08-31 10 views
5

W aplikacji ASP.net używam formantu Login z niestandardowym dostawcą członkostwa, który napisałem. Co chcę zrobić, to ustawić Thread.CurrentPrincipal do mojego niestandardowego obiektu głównego, zaraz po uwierzytelnieniu użytkownika.Jak ustawić Thread.CurrentPrincipal do użytku w całej aplikacji?

Używam settera: Thread.CurrentPrincipal i ustawia on dla mnie obiekt główny, ale na wszystkich następnych wątkach ta właściwość CurrentPrincipal jest nadpisywana domyślną.

Oto mój kod dla zdarzenia Authenticate kontroli logowanie:

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; 
     } 
    } 

Na przykład, wyobraźmy sobie, że mogę się zalogować przy użyciu nazwy użytkownika A, wszystko idzie dobrze ... przechodzi walidacji, ale hardcode użytkownikowi z nazwą użytkownika B w obiekcie tożsamości, który jest ustawiony na główny obiekt, który ustawiłem jako obiekt CurrentPrincipal.

Kiedy sprawdzić, który użytkownik jest ustawiony na CurrentPrincipal Tożsamości pod koniec tej metody to mówi, że to użytkownik B. Ale gdy załadować kolejną stronę, a następnie sprawdzić, co Tożsamość CurrentPrincipal jest, to mówi, że to użytkownik A.

Co zrobić, aby mój obiekt CurrentPrincipal był trwały we wszystkich innych wątkach i gdzie/kiedy ta kontrola logowania ustawi obiekt CurrentPrincipal wątku?

+0

Co robisz? Czy chcesz, aby wszyscy byli identyfikowani jako pierwszy zalogowany użytkownik? Musisz zrozumieć mechanizmy uwierzytelniania i autoryzacji aplikacji internetowych, korzystania z plików cookie itp. Nie możesz ustawić jednej głównej dla wszystkich wątków aplikacji dla wielu użytkowników. –

+0

Oczywiście, że nie. Może nie wyraziłem się wystarczająco jasno. – Goran

Odpowiedz

1

Można obsługiwać FormsAuthentication_OnAuthenticate (obiekt nadawca, FormsAuthenticationEventArgs e) (w Global.asax) i ustawić CurrentPrincipal tutaj.


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

Pozwól mi wyjaśnić to więcej ... Używam już uwierzytelniania formularzy, jeśli nie zauważyłeś ... Chodzi o to, że chcę przechowywać identyfikator użytkownika (wraz z kilkoma innymi informacjami o użytkowniku) w obiekcie tożsamości wątku .CurrentPrincipal, więc zaimplementowałem własne obiekty Principal i Identity i zmienię metodę Authenticate kontrolki Login w uwierzytelnianiu Forms. – Goran

+0

Spróbuję tego teraz ... – Goran

2

Tadas nie jest błędny, poprawnie zaimplementowane FormsAuthentication nie spowoduje tego problemu.

Twoja strona jest dostępna nawet bez logowania, tylko na stronie logowania, zasada twojego wątku jest ustawiana ręcznie przez ciebie, ale kiedy trafisz na inny URL, to na pewno nie wywołuje twojej strony logowania i pamiętaj, że każda strona działa na własną rękę inny wątek. Jeśli zażądasz pierwszej strony i zasady ustawiania wątku i zażądasz drugiej strony w tej samej instancji przeglądarki, może ona być lub nie być dokładnie tym samym wątkiem.

ten sposób FormsAuthentication działa

  1. sprawdza czy Auth Cookie jest ustawiona czy nie, to wtedy kieruje użytkownika do strony logowania
  2. login strona musi potwierdzić i ustawić plik cookie uwierzytelniania, jak FormsAuthentication.SetAuthCookie
  3. Przed każdym dostępem do strony wykonywany jest krok 1.
  4. Po pomyślnym sprawdzeniu autentyczności Auth Cookie, ASP.NET wewnętrznie ustawia bieżącego użytkownika i wszystkie parametry differnet zgodnie z twoim składnikiem członkostwa.
  5. plik
  6. ASP.NET Global.asax może dać pewne zdarzenia gdzie można plugin swój kod, aby sprawdzić tylko po autoryzacji powiedzie można zmienić bieżącego użytkownika, należy pamiętać, ustawienie aktualnego zasadę na stronie logowania nie pomoże

Mieliśmy podobny problem, gdy używaliśmy sesji do przechowywania pewnych ważnych informacji, po tym jak sesje auth nie zostały przebudowane, więc napisaliśmy moduł HTTP, a w jego metodzie init załączyliśmy wydarzenie AfterRequestAcquired i w tym przypadku możesz napisać swoje Kod do tworzenia wszystkich ważnych zmiennych związanych z użytkownikiem.

1

To, co zrobiłem w metodzie 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."); 
     } 

wydaje się, że to działa, co należy zrobić ... To jest po prostu, że jeśli kładę niestandardową parę główny/tożsamość jako e.User, następnie Mam problem z serializacją, który muszę naprawić ... Dziękuję ...

+0

Problem z serializacją po prostu zniknął, gdy przełączyłem się na IIS zamiast używać serwera Visual Studio Development. – Goran

Powiązane problemy