2012-09-18 16 views
5

Próbuję przekierować użytkownika do innej akcji, jeśli jego adres e-mail nie został zweryfikowany. Chodzi o to, że nie chcę ich wylogować, po prostu chcę je przekierować. Kiedy robię to w OnAuthorization dla kontrolera, przekierowuje zgodnie z oczekiwaniami, ale użytkownik nie jest uwierzytelniony. Nie jestem pewien, dlaczego tak jest. Mój kod wygląda następująco:Przekierowanie MVC w trybie Autoryzacja powoduje niepowodzenie autoryzacji

protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 

     //_applicationService.CurrentUser is populated correctly at this point 
     // from Controller.User 
     if (_applicationService.CurrentUser != null) 
     { 
      if (_applicationService.CurrentUser.EmailVerified != true) 
      { 
       var url = new UrlHelper(filterContext.RequestContext); 
       var verifyEmailUrl = url.Action("EmailVerificationRequired", "Account", null); 
       filterContext.Result = new RedirectResult(verifyEmailUrl); 
      } 
     } 

    } 

Uwaga: Usunąłem niepotrzebny kod, aby było bardziej zrozumiałe. _applicationService.CurrentUser jest zapełniony bieżącym użytkownikiem - i użytkownik został poprawnie uwierzytelniony, gdy dojdzie do tego punktu. Ale po przekierowaniu użytkownik nie jest już uwierzytelniany.

Jak mogę uzyskać to przekierowanie bez wpływu na autoryzację użytkownika?

Próbowałem wprowadzić mój kod do OnActionExecuting, a także próbowałem go wdrożyć w niestandardowej ActionFilterAttribute, ale gdziekolwiek umieścić to przekierowanie w nim zapobiega "Użytkownikowi" (tj: System.Security.Principal .IPrincipal Controller.User) od uzyskania uwierzytelnienia.

Czego mi tu brakuje? Mam nadzieję, że to ma sens. Każda pomoc doceniona.

W odpowiedzi na wniosek Darin za mojego działania logowanie:

[HttpPost] 
    [AllowAnonymous] 
    public ActionResult Login(LoginViewModel model, string returnUrl) 
    { 
     string errorMessage = "The username or password is incorrect"; 

     if (ModelState.IsValid) 
     { 
      if (_contextExecutor.ExecuteContextForModel<LoginContextModel, bool>(new LoginContextModel(){      
       LoginViewModel = model 
      })) 
      { 
       ViewBag.CurrentUser = _applicationService.CurrentUser; 
       _formsAuthenticationService.SetAuthCookie(model.LoginEmailAddress, model.RememberMe); 

       if (_applicationService.IsLocalUrl(returnUrl)) 
       { 
        return Redirect(returnUrl); 
       } 

       return RedirectToAction("Index", "Home").Success("Thank you for logging in."); 
      } 
      else 
      { 
       errorMessage = "Email address not found or invalid password."; 
      } 
     } 

     return View(model).Error(errorMessage); 
    } 
+0

Czy możesz pokazać, w jaki sposób uwierzytelniasz użytkownika - twoją akcję "LogOn"? –

+0

@DarinDimitrov - Dodałem moją akcję logowania zgodnie z żądaniem. – soupy1976

+0

Tego właśnie szukałem! Zaoszczędziłam dużo czasu – JosephDoggie

Odpowiedz

3

Dobra, już znalazłem, gdzie się nie myliłem. Problemem było to, że jest trochę goon i nie w pełni zrozumieć, co się dzieje, gdy robiłem:

filterContext.Result = new RedirectResult(verifyEmailUrl); 

nie zdawałem sobie sprawy, że ja faktycznie rozpoczynając nowy wniosek z tego, Pomyłkowo myślałem, że właśnie przekierowuję do innej akcji. Teraz wydaje się oczywiste, że będzie to nowa prośba.

Problem polegał na tym, że moja akcja EmailVerificationRequired nie autoryzowała użytkownika, a zatem kiedy dotarła do tej akcji, bieżący użytkownik miał wartość zerową. Naprawiono więc autoryzację dla tej akcji i teraz wszystko jest w porządku.

Dzięki za pomoc dla facetów.

0

Można sobie z tym poradzić w swojej logowania ActionResult. Spróbuj natychmiast umieszczenie kodu

 if (_applicationService.CurrentUser.EmailVerified != true) 
     { 
      FormsAuthentication.SignOut(); 
      return RedirectToAction("EmailVerificationRequired", "Account"); 
     } 

po tej linii:

_formsAuthenticationService.SetAuthCookie(model.LoginEmailAddress, model.RememberMe);  

Następnie ustawić punkty przerwania i krok poprzez działanie logowania. Jeśli nie dotrzesz do linii jeśli (_applicationService.CurrentUser.EmailVerified! = True), oznacza to, że Twój użytkownik nie jest uwierzytelniony i masz inny problem z adresem.

+1

Dzięki za pomoc. Chodzi o to, chcę to sprawdzić za każdym razem, gdy dostęp do jakiejkolwiek akcji wymagającej uwierzytelnienia jest możliwy. W przeciwnym razie użytkownik, który byłby zalogowany, ale którego adres e-mail nie został zweryfikowany, nadal będzie mógł uzyskać dostęp do części witryny, wpisując adres URL. Właśnie dlatego chciałem, aby był on w OnAuthorization, a nie tylko umieszczał go w akcji logowania. – soupy1976

+0

@ soupy1976 Na podstawie Twojego komentarza edytowałem próbkę kodu, aby uniemożliwić użytkownikowi dostęp do bezpiecznych części witryny bez uwierzytelniania i sprawdzania poczty e-mail. Mam nadzieję że to pomoże. – Tarzan

+0

jeszcze raz dziękuję za pomoc Tarzan. Problem z umieszczeniem tego sprawdzenia w akcji logowania polega na tym, że użytkownik nadal będzie mógł uzyskać dostęp do zawartości, wpisując adres URL w przeglądarce (jeśli zdarzyło się, że to wiedział lub zapisał w swojej historii lub coś takiego). Muszę to zrobić w autoryzacji podczas faktycznego żądania strony, a nie tylko sprawdzać je podczas logowania, w przeciwnym razie nie ma prawie żadnego zabezpieczenia. – soupy1976

Powiązane problemy