2014-10-03 27 views
9

Posiadam standardową klasę AccountController z projektu ASP.NET MVC5. Podczas próby wylogowania użytkownika napotykam błąd o numerze HttpContext: null. (Mam na myśli tutaj HttpContext.GetOwinContext(). Authentication jest null)Jak się wylogować użytkownika w OWIN ASP.NET MVC5

Więc nie mogę się w jaki sposób możemy się wylogować użytkownika po zakończeniu sesji ...

W global.asax mam to

protected void Session_Start(object sender, EventArgs e) 
{ 
    Session.Timeout = 3; 
} 

protected void Session_End(object sender, EventArgs e) 
{ 
      try 
      { 
       var accountController = new AccountController(); 
       accountController.SignOut(); 
      } 
      catch (Exception) 
      { 
      } 
} 

AccountController

public void SignOut() 
{ 
     // Even if I do It does not help coz HttpContext is NULL 
     _authnManager = HttpContext.GetOwinContext().Authentication;  

    AuthenticationManager.SignOut(); 


} 

private IAuthenticationManager _authnManager; // Add this private variable 


public IAuthenticationManager AuthenticationManager // Modified this from private to public and add the setter 
{ 
      get 
      { 
       if (_authnManager == null) 
        _authnManager = HttpContext.GetOwinContext().Authentication; 
       return _authnManager; 
      } 
      set { _authnManager = value; } 
} 

Startup.Auth.cs ma

public void ConfigureAuth(IAppBuilder app) 
     { 
      // Enable the application to use a cookie to store information for the signed in user 
      app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       ExpireTimeSpan = TimeSpan.FromMinutes(3), 
       AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
       LoginPath = new PathString("/Account/Login") 
      }); 
} 

Odpowiedz

2

W tym celu należy zdefiniować atrybut ActionFilter i tam należy przekierować użytkownika do odpowiedniej akcji kontrolera. Tam musisz sprawdzić wartość sesji, a jeśli jej wartość null, musisz przekierować użytkownika. Oto kod poniżej (Also you can visit my blog for detail step):

public class CheckSessionOutAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower().Trim(); 
      string actionName = filterContext.ActionDescriptor.ActionName.ToLower().Trim(); 

      if (!actionName.StartsWith("login") && !actionName.StartsWith("sessionlogoff")) 
      { 
       var session = HttpContext.Current.Session["SelectedSiteName"]; 
       HttpContext ctx = HttpContext.Current; 
       //Redirects user to login screen if session has timed out 
       if (session == null) 
       { 
        base.OnActionExecuting(filterContext); 


        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new 
        { 
         controller = "Account", 
         action = "SessionLogOff" 
        })); 

       } 
      } 

     } 

    } 
} 
8

Wywołanie Session_End() jest powodującej wyjątek. Jest to całkowicie oczekiwane, ponieważ nie można po prostu utworzyć new AccountController(), zadzwoń pod numer accountController.SignOut() i oczekiwać, że zadziała. Ten nowy kontroler nie jest podłączony do potoku MVC - nie ma HttpContext i wszystkich innych wymagań, aby mógł działać.

Należy wylogować użytkowników w odpowiedzi na złożone przez nich żądanie. Utwórz nowy projekt MVC z uwierzytelnianiem indywidualnych kont. Otwarte AccountController i przyjrzeć się metodzie LogOff():

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult LogOff() 
    { 
     AuthenticationManager.SignOut(); 
     return RedirectToAction("Index", "Home"); 
    } 

Tutaj AuthenticationManager.SignOut() zostanie wykonany w odpowiedzi na żądanie POST AT/Konta/wylogowywanie. Kiedykolwiek takie żądanie dotrze, ASP.NET/MVC utworzy instancję AccountController i zainicjuje ją poprawnie. Następnie zostanie wywołana metoda LogOff, w której można faktycznie wykonać AuthenticationManager.SignOut();.

także w domyślnym ASP.NET/MVC Application z tożsamością deklaruje AuthenticationManager w Pomocników region kodu następująco:

private IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } } 

Nadzieja to pomaga.

+0

Tak, zgadzam się. Domyślnie mamy tę metodę, ale chciałbym wymusić wylogowanie użytkownika i przekierowanie go na stronę logowania. Potrzebuję więc rozwiązania, by zrobić to z OWINEM. W każdym razie dziękuję za twoją opinię! –

+0

@ClarkKent To rozwiązanie działa z OWINEM, zredagowałem odpowiedź, aby wyjaśnić, jak to działa. Zobacz oczekujące zmiany. Milan wyjaśnia, dlaczego zgłasza błąd, zanim wylogujesz się z użytkowników. – Termato

+0

Cóż ... Ijust skomentował kod w 'Session_End' i mam do czynienia z dziwnym zachowaniem aplikacji. Wpisuję SessionTimeout 1 min. Kiedy się loguję i nic nie robię, wszystko działa dobrze. Tak więc 1 minutę później, gdy odświeżam strony, wylogowuje się i przekierowuje na stronę LOGIN. Ale jeśli w ciągu 2-3 minut. Nawiguję w witrynie, która nie działa. :) –

12

Zakładając, że używasz ApplicationCookie przechowywać swoje dane logowania.

AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); 
+0

Mówi, że AuthManager nie ma metody "SignOut" – Phil

+1

Możesz spróbować z var ctx = Request.GetOwinContext(); var authenticationManager = ctx.Authentication; authenticationManager.SignOut (DefaultAuthenticationTypes.ApplicationCookie); – radbyx

2

Próbowałem to wszystko się:

System.Web.HttpContext.Current.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie); 
FormsAuthentication.SignOut(); 
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); 

Request.GetOwinContext().Authentication.SignOut(); 

Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie); 

ale ostatecznie to rozwiązać mój problem:

HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty),null); 

Check

1
Session.Abandon(); 
var owinContext = System.Web.HttpContext.Current.Request.GetOwinContext(); 
var authenticationTypes = owinContext.Authentication.GetAuthenticationTypes(); 
owinContext.Authentication.SignOut(authenticationTypes.Select(o => o.AuthenticationType).ToArray()); 

`` `

1

ten pracował dla mnie

`public void SignOut() 
    { 
     IOwinContext context = _context.Request.GetOwinContext(); 
     IAuthenticationManager authenticationManager = context.Authentication; 
     authenticationManager.SignOut(AuthenticationType); 
    } 
` 

Jedyny problem mam, to nie ma przekierowanie do strony logowania, więc dostać się widok nie znaleziono błąd, ponieważ widok z I wylogować jest pod [Autoryzacja] atrybutu. Myślałem, że automatyczne przekierowanie zostało wbudowane, gdy użytkownik nie jest autoryzowany przez ten blok kodu ...

`app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = "ApplicationCookie", 
     LoginPath = new PathString("/Account/Login"), 
     ExpireTimeSpan = TimeSpan.FromHours(1), 
    }); 
`