locked
How to set expiration time for a cookie RRS feed

  • Question

  • User-259252065 posted

    Hi. I'm implementing asp.net core 3.1. And I'm using ldap authentication in my code. I have 2 cookies in my code. One of them is for authentication and it is in startup.cs and the other cookie is for holding the name of the user to show it in the panel and I also use it for saving the log of who inserted data. My problem is I set the time of the authentication cookie to be 15 min but I need to send the expiration time of authentication cookie to the cookie that holds the user's name. Here is what I have tried till now:

    //startup.cs
    
     services.AddScoped<IAuthenticationService, LdapAuthenticationService>();
    
                services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
                {
                    // Cookie settings
                    options.Cookie.Name = "UserLoginCookie"; // Name of cookie  
                    options.Cookie.HttpOnly = true;
    // Here its expiration time is 15 min
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(15);
    
                    options.LoginPath = "/Account/Login";
                    options.AccessDeniedPath = "/Account/UserAccessDenied";
                    options.SlidingExpiration = true;
                });
    
    //Here is my AccountController
    
     public IActionResult Login()
            {
                return View();
            }
    
    
            [HttpPost]
            public async Task<IActionResult> Login(LoginModel model)
            {
                LdapEntry result1 = null;
                var result = _authenticationService.ValidateUser("me.fr", model.UserName, model.Password);
    
                if (result)
                {
    
                    var user = mycontext.Role.Where(u => u.UserName == model.UserName).SingleOrDefault();
    
                    result1 = _authenticationService.GetLdapUserDetail("me.fr", model.UserName, model.Password);
                    ViewBag.Username = result1.GetAttribute("CN").StringValue;
    
                    Index(result1.GetAttribute("CN").StringValue);
    
                    var claims = new List<Claim>
                {
    
                        new Claim("UserName", user.UserName),
                        new Claim(ClaimTypes.Name, user.Name),
                        new Claim(ClaimTypes.Email, user.EmailId),
                        new Claim(ClaimTypes.Role, user.UserRole)
    
                        };
    
                    var claimsIdentity = new ClaimsIdentity(
                        claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
                    //For deleting cookie after closing the browser
    
                    var authProperties = new AuthenticationProperties
                    {
    
                        IsPersistent = false
    
                    };
                    await HttpContext.SignInAsync(
                            CookieAuthenticationDefaults.AuthenticationScheme,
                            new ClaimsPrincipal(claimsIdentity),
                            authProperties);
    
                }
                else
                {
                    Console.writeln("error");
                }
                return RedirectToAction(nameof(HomeController.Index), "Home");
            }
    
            public IActionResult Index(string str)
            {
    
                string cookieValueFromContext = _httpContext.HttpContext.Request.Cookies["mystr"];
        
    
                mycookie.Set("mystr", str, 15);
                  
                return View();
            }
    
    //Here is MyCookie.cs
    
      public class MyCookie
        {
            private readonly IHttpContextAccessor _httpContext;
    
            public MyCookie(IHttpContextAccessor context)
            {
                _httpContext = context;
            }
            public void Set(string key, string value, int? expireTime)
            {
                CookieOptions option = new CookieOptions();
    
                if (expireTime.HasValue)
                    option.Expires = DateTime.Now.AddMinutes(expireTime.Value);
                else
                    option.Expires = DateTime.Now.AddMilliseconds(10);
    
                _httpContext.HttpContext.Response.Cookies.Append(key, value, option);
            }
    
            public string Get(string key)
            {
                return _httpContext.HttpContext.Request.Cookies[key];
            }
        }

    My problem is although the authentication cookie is alive while I'm working with the system, the cookie that holds the name after 15 miniutes gets erased.

    Tuesday, February 23, 2021 2:38 PM

Answers

  • User475983607 posted

    The design makes no logical sense.  Simply save the LDAP common name (CN) in a claim in the authentication cookie.  You'll have access to the CN in every controller.

    ViewBag.Username = result1.GetAttribute("CN").StringValue;
    
    var claims = new List<Claim>
    {
    
        new Claim("UserName", user.UserName),
        new Claim(ClaimTypes.Name, user.Name),
        new Claim(ClaimTypes.Email, user.EmailId),
        new Claim(ClaimTypes.Role, user.UserRole),
        new Claim("CN", result1.GetAttribute("CN").StringValue;)
    };

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, March 3, 2021 11:24 AM

All replies

  • User-474980206 posted

    The authentication cookie is set to have a sliding window. That means before the cookie expires a new one is created. You do not have the same code for your custom cookie.

    Tuesday, February 23, 2021 3:47 PM
  • User-259252065 posted

    Thank you for your reply. Could you please guid me how to implement it or showing an example?

    Tuesday, February 23, 2021 5:47 PM
  • User475983607 posted

    Use the standard authentication cookie API in Core and persist whatever claims/roles you like.  There is no good reason for two cookies.

    https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-5.0

    Tuesday, February 23, 2021 7:35 PM
  • User-259252065 posted

    Thank you for your reply. As you can see in method public async Task<IActionResult> Login(LoginModel model), I have an expression like below to get the user's name from server:

    Index(result1.GetAttribute("CN").StringValue);

    the above method is in a controller called Account. I need the value of result1.GetAttribute("CN").StringValue in an other controller called itemRequester. Thats why I used a cookie to handle it and now as I mentioned its expiration time is not slidingwindow. Is there any way other than using cookie to pass the mentioned data from AccountController to itemRequester controller?

    Wednesday, March 3, 2021 8:21 AM
  • User475983607 posted

    The design makes no logical sense.  Simply save the LDAP common name (CN) in a claim in the authentication cookie.  You'll have access to the CN in every controller.

    ViewBag.Username = result1.GetAttribute("CN").StringValue;
    
    var claims = new List<Claim>
    {
    
        new Claim("UserName", user.UserName),
        new Claim(ClaimTypes.Name, user.Name),
        new Claim(ClaimTypes.Email, user.EmailId),
        new Claim(ClaimTypes.Role, user.UserRole),
        new Claim("CN", result1.GetAttribute("CN").StringValue;)
    };

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, March 3, 2021 11:24 AM