问题
I have got a standard AccountController class of ASP.NET MVC5 project.
When I try to log out user I am facing an error coz HttpContext
is null
. (I mean here HttpContext
.GetOwinContext().Authentication is null)
So I cannot get how we can logout user when session ends...
In global.asax I have got this
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 has
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")
});
}
回答1:
For this you need to define a ActionFilter attribute and there you need to redirect the user to the respective controller action. There you need to check for the session value and if its null then you need to redirect the user. Here is the code below( 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"
}));
}
}
}
}
}
回答2:
Assuming that you are using ApplicationCookie to store your login information.
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
回答3:
A call to Session_End() is causing the exception. That is totally expected since you cannot simply create new AccountController()
, call accountController.SignOut()
and expect it to work. This new controller is not wired up into the MVC pipeline - it does not have HttpContext and all its other requirements to be able to work.
You should log users out in response to a request that they have made. Create a new MVC project with Individual Accounts authentication. Open AccountController and take a look at the LogOff()
method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut();
return RedirectToAction("Index", "Home");
}
Here AuthenticationManager.SignOut()
will be executed in response to a POST request at /Account/LogOff. Whenever such request arrives the ASP.NET/MVC will create an instance of AccountController and initialize it properly. After that the LogOff method will be called where you can actually execute AuthenticationManager.SignOut();
.
Also in the default ASP.NET/MVC Application with Identity declares AuthenticationManager in the Helpers region of the code as follows:
private IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } }
Hope this helps.
回答4:
I tried all this out:
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);
but finally this solved my problem:
HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty),null);
Check
回答5:
Session.Abandon();
var owinContext = System.Web.HttpContext.Current.Request.GetOwinContext();
var authenticationTypes = owinContext.Authentication.GetAuthenticationTypes();
owinContext.Authentication.SignOut(authenticationTypes.Select(o => o.AuthenticationType).ToArray());
```
回答6:
This worked for me
`public void SignOut()
{
IOwinContext context = _context.Request.GetOwinContext();
IAuthenticationManager authenticationManager = context.Authentication;
authenticationManager.SignOut(AuthenticationType);
}
`
The only problem I have is there's no redirect to Login so I get a view not found error because the view I logged out from is under an [Authorize] attribute. I thought the automatic redirect was built in when a user is not authorized by this code block...
`app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "ApplicationCookie",
LoginPath = new PathString("/Account/Login"),
ExpireTimeSpan = TimeSpan.FromHours(1),
});
`
来源:https://stackoverflow.com/questions/26182660/how-to-logout-user-in-owin-asp-net-mvc5