2014-10-03 31 views
9

我有一个标准的AccountController类的ASP.NET MVC5项目。 当我尝试注销用户时,我遇到了错误,因为HttpContextnull。 (我的意思是HttpContext.GetOwinContext()认证为null)如何在OWIN ASP.NET MVC5中注销用户

所以我不能让会话结束时,我们如何注销用户...

Global.asax的我有这

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

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

回答

2

为此,您需要定义一个ActionFilter属性,并且您需要将用户重定向到相应的控制器操作。在那里你需要检查会话值,如果它为空,那么你需要重定向用户。这里是低于(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

Session_End中()引起异常的调用。这是完全可以预料的,因为你不能简单地创建new AccountController(),请致电accountController.SignOut()并期望它能够正常工作。这个新的控制器没有连接到MVC管道 - 它没有HttpContext和所有其他要求能够工作。

您应该记录用户以响应他们的请求。使用个人帐户身份验证创建一个新的MVC项目。开放的AccountController看一看在LogOff()方法:

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

AuthenticationManager.SignOut()这里将响应于在/帐户/注销POST请求来执行。每当这样的请求到达时,ASP.NET/MVC将创建一个AccountController实例并正确初始化它。之后,将调用LogOff方法,您可以在其中实际执行AuthenticationManager.SignOut();

也在默认ASP.NET/MVC应用与身份声明的AuthenticationManager助手代码区域如下:

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

希望这有助于。

+0

是的,我同意。我们默认有这种方法,但我想强制注销用户并将其重定向到登录页面。所以我需要解决方案来与OWIN做到这一点。无论如何感谢您的意见! – 2014-10-03 17:05:00

+0

@ClarkKent这个解决方案确实可以和OWIN做到,我编辑了答案来解释它是如何做到的。请参阅待处理的修改。米兰解释了为什么它会在您注销用户之前抛出错误。 – Termato 2014-10-03 17:06:55

+0

那么...... Ijust在'Session_End'中评论了代码,我面临着应用程序的奇怪行为。我把SessionTimeout 1分钟。当我登录并且什么都不做时,它工作正常。所以1分钟后,当我刷新页面时,它会注销并重定向到LOGIN页面。但是如果在2-3分钟内。我正在浏览网站,它不工作。 :) – 2014-10-03 17:24:56

12

假设你正在使用ApplicationCookie来存储您的登录信息。

AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); 
+0

它表示AuthManager没有方法'SignOut' – Phil 2017-04-20 13:50:12

+1

您可以尝试使用 var ctx = Request.GetOwinContext(); var authenticationManager = ctx.Authentication; authenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); – radbyx 2017-05-05 06:08:09

2

我想这一切了:

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

但最后这个解决我的问题:

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

这为我工作

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

我唯一的问题是有没有重定向登录,所以我得到未找到错误,因为我从注销的观点是[授权]属性下的视图。我认为自动重定向内置于当用户未被此代码块授权时...

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