1

I have created Login/ Logout functionality using ASP.Net MVC 4. I used my own created form for authenticate users against Active Directory. It is working fine with the functionality.

Still there is a big issue in security. Once user click on the logout link he/ she successfully logged out and redirected to login form again. Code in the controller looks like below.

    public ActionResult Logout()
    {
        // Tried to include below 3 lines in _Layout.cshtml as well. But not identifying.
        Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
        Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
        Response.Cache.SetNoStore();            

        Session.Abandon();              

        return RedirectToAction("Login");
    }

BUT, once Browser back button clicked, the user can go back to the other pages and navigate thru pages.

I went thru several solutions, different approaches but none worked out. Seems the MVC approach is very different from ASP.NET forms. Appreciate your help on this.

(I'm looking to solve this using C#/ MVC way. Not using JavaScript to disable/ close the browser on logout.)

UPDATE: Code fragments

    [HttpPost]
    public ActionResult Login(LoginModel authUser)
    {
        // Call Helper to get LDAP info. Will return username with groups or null      
        UserModel userProfile = LdapLoginHelper.AuthenticateUser(authUser);

        if (userProfile != null)
        {                
            Session["UserName"] = userProfile.UserName;
            Session["LdapGroups"] = userProfile.LdapGroups;

            if (userProfile.LdapGroups.Contains("Administrators"))
            {
                // To be implemented                   
            }
            else
            {
                // To be implemented      
            }

            // Successful login. Redirect to main page
            return RedirectToAction("Home", "Home");
        }
        else
        {
            // Invalid Login. Redirect to Login page
            return RedirectToAction("Login");
        }            
    }



    public ActionResult Logout()
    {
        // Not worked
        Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
        Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
        Response.Cache.SetNoStore();
        Session.Abandon();

        /// Tried this too. Not worked.
        /// Session.Clear();
        /// FormsAuthentication.SignOut();

        //// Tried this also. Not worked.
        //// WebSecurity.Logout();

        return RedirectToAction("Login");
    }

In addition to this common _Layout.cshtml page header looks like below.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="CACHE-CONTROL" content="NO-CACHE">
.
. 
.
chatura
  • 4,097
  • 4
  • 19
  • 19
  • did you decorate your controllers / actions with [Authorize] attribute ? how is the authentication information persisted? normally you have session and a cookie used for auth. Are you sure your user is no longer authenticated after your Logout() action ? – Paweł Staniec Jan 20 '13 at 13:47
  • Still I'm working on writing a custom attribute for authorization. Once user is logged in username is assigned to a session variable. – chatura Jan 20 '13 at 13:58
  • Can you show us how you your Login method looks like? A few words on why you don't want to use ASP.NET built-in authorization/authentication features would also help – Paweł Staniec Jan 20 '13 at 19:40
  • Will update with the Login, Logout code snippets. ASP.NET built-in authorization/authentication features not used due to clients' request and they will use Active Directory instead. – chatura Jan 21 '13 at 04:04
  • How about trying the solution from here: http://stackoverflow.com/questions/16337149/how-to-clear-browser-cache-on-browser-back-button-click-in-mvc4/16337566#16337566 – von v. Feb 04 '15 at 00:50

3 Answers3

1

add the following code in your global.asax page and remove first 3 lines from your logout() function.

protected void Application_BeginRequest()
{
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1));
    Response.Cache.SetNoStore();
}
sudil ravindran pk
  • 2,996
  • 3
  • 24
  • 29
0

I've only used SetExpires with DateTime.Now that would match you local server time to the cookie. Using DateTime.UtcNow.Addminutes(-1) could be the real culprit here.

Also, if your are using forms authentication, I don't see your call to

FormsAuthentication.SignOut();
  • Thats exactly wut I was going to recommend. In fact...I think the default mvc template generates an account controller with login/logout logic so should be able use that as a point of reference. – A-Dubb Jan 20 '13 at 14:17
  • Mvc4 is doing OpenAuth in the template. As if Facebook is your default provider. This is one of the first thing you scuttle if using that template. The question implies that openauth was kicked for forms. – Michael Viktor Starberg Jan 20 '13 at 16:57
  • @MichaelViktorStarberg not sure if I understood your comment but MVC4 template has OpenAuth and WebSecurity with SimpleMembership which replaced existing ASP.NET Role and Membership, so you don't have authenticate to Facebook. Good read : http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx – Paweł Staniec Jan 20 '13 at 19:48
  • Tried with FormsAuthentication.SignOut(); too but back button scenario is still there. Will update the question with the code. Clients' request is use AD/ LDAP for authentication based on groups for authorization. – chatura Jan 21 '13 at 04:07
  • Did you try not using UtcNow? – Michael Viktor Starberg Jan 21 '13 at 18:17
  • @Michael Viktor Starberg - Yes tried all the combinations. Logout is done but back button issue is there. After go back session is not there (nothing display in user name like User:)but can navigate to all internal pages. – chatura Jan 24 '13 at 07:10
0

Adding the following attribute to any ActionResult methods which return secure pages in your controller(s) should work:

public class MyControllerForAuthorizedStuff
{
    [OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]
    public ActionResult Index()
    {
        return View();
    }
} 
Matthew Dresser
  • 11,273
  • 11
  • 76
  • 120