ASP.Net External Cookie with Sliding Expiration appearing as a Session cookie - asp.net

I am trying to configure a sliding expiration cookie in Asp.Net. I am expecting the cookie to appear in the Google Chrome developer tools cookie manager with an expiration date 5 minutes after authentication, but it shows as "Session" and never expires until the sign-out button is clicked. It does go away if the browser is closed.
Below is the code as it currently stands. The website uses Saml based Single-Sign-On authentication with Kentor.AuthServices nuget package (now known as SustainSys.Saml2, we are behind in versions).
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/signin"),
CookieSecure = CookieSecureOption.SameAsRequest,
ExpireTimeSpan = TimeSpan.FromMinutes(5),
SlidingExpiration = true,
Provider = new CookieAuthenticationProvider
{
OnApplyRedirect = ctx => { },
OnResponseSignIn = context =>
{
context.Properties.AllowRefresh = true;
context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(5);
}
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
Kentor.AuthServices.Configuration.Options.GlobalEnableSha256XmlSignatures();
The OnResponseSignIn block was recently added based on this MSDN answer:
https://forums.asp.net/t/2121970.aspx?OWIN+Authentication+ExpireTimeSpan+not+working
I want the cookies to expire in a 30-minute inactive period. The above code is set to 5 for ease of testing.

The developer tools show the cookie expiration time. This is not directly related to the authentication token expiration time, which should in fact be correct for your code too.
As indicated by this comment "The expiration information is stored in the protected cookie ticket". The token expiration time should take effect properly, even if you cannot see it in the developer tools as it's encrypted inside the cookie itself.

Related

ASP.NET Core AntiforgeryToken cookie is set to 1969 as expiration time

I have setup an authentication using simply cookies. Somehow I saw in Application tab of Chrome that antiforgery token cookie expiration time is set to 1969, 31st December.
In ConfigureServices I have:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(opts =>
{
var ts = TimeSpan.FromMinutes(30);
opts.Cookie.HttpOnly = true;
opts.Cookie.Expiration = ts;
opts.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
opts.LoginPath = new PathString("/User/Authenticate");
opts.ExpireTimeSpan = ts;
opts.Cookie.MaxAge = ts;
opts.Validate();
});
and in Configure
app.UseCookiePolicy();
app.UseAuthentication();
Does it is a security concern ? Can that token be bypassed ? I didn't find any article related to antiforgery token default expiration date.
Setting the date of a cookie to a time in the past (or minimum time) is a very common technique of telling the browser to delete a cookie. You should not be concerned.

Created a mvc5 app with Identity2, how do i set it up to use session cookies, so they expire when the browser closes

Created a mvc5 app with Identity2,using google login (pretty much the empty app, with google stuff turned on)
How do I set it up to use session cookies, so they expire when the browser closes.
The app will be used by students who may hot swap seats, so i need the login to expire when the browser closes.
I read an SO article that implies this is the default, but when i close the browser, and go back to the site, it remembers the google login.
Edit
Sorry to burst everyone bubble, but this isn't a duplicate.
It reproduced in Chrome after the settings in the supposed "answer" are changed, and it also reproduces in IE... This is an Asp.net Identity 2 +Google login issue, not a Chrome issue.
Edit
Adding Startup Auth file for Setup Help
using System;
using System.Configuration;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Owin;
using StudentPortalGSuite.Models;
namespace StudentPortalGSuite
{
public partial class Startup
{
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(
new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes( 30 ),
regenerateIdentity: ( manager, user ) => user.GenerateUserIdentityAsync( manager )
)
},
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
// per https://learn.microsoft.com/en-us/aspnet/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on - EWB
//dev-jcsn email
app.UseGoogleAuthentication( new GoogleOAuth2AuthenticationOptions()
{
ClientId = "...",
ClientSecret = "..."
} );
//});
}
}
}
EDIT
The use case I'm trying to fix is, since our app is used in a classroom, that student A Closes his/her browser instead of logging out, and then next user tries to login. As it stands they are autologged into user A's account.
I'd also be up for a way to 100% log out the user when redirected to the login page, but all the ways I've tried that aren't working.
Maybe you can catch the window close event on page and call logout method
$(window).on("beforeunload", function() {
//ajax call to a post controller that logs the user out
})
Calling this at the top of the LogIn controller Method solved the issue.
Request.GetOwinContext().Authentication.SignOut( DefaultAuthenticationTypes.ApplicationCookie );// https://stackoverflow.com/questions/28999318/owin-authentication-signout-doesnt-seem-to-remove-the-cookie - stralos s answer
Request.GetOwinContext().Authentication.SignOut( DefaultAuthenticationTypes.ExternalCookie );

How do I issue the corresponding Bearer and Cookie identity in ASP.NET with multiple Authorization schemes?

This documentation describes in part how to use more than one authentication scheme:
In some scenarios, such as Single Page Applications it is possible to end up with multiple authentication methods. For example, your application may use cookie-based authentication to log in and bearer authentication for JavaScript requests. In some cases you may have multiple instances of an authentication middleware. For example, two cookie middlewares where one contains a basic identity and one is created when a multi-factor authentication has triggered because the user requested an operation that requires extra security.
Example:
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationScheme = "Cookie",
LoginPath = new PathString("/Account/Unauthorized/"),
AccessDeniedPath = new PathString("/Account/Forbidden/"),
AutomaticAuthenticate = false
});
app.UseBearerAuthentication(options =>
{
options.AuthenticationScheme = "Bearer";
options.AutomaticAuthenticate = false;
});
However it only describes how to use Bearer or Cookie auth. What isn't clear is what other combinations are valid, or how to properly issue bearer or cookies to the client.
How can that be accomplished?
One common use case for this which large sites like Facebook, Google etc. use is to use multiple cookie authentication middleware's and set one of them to be the default using AutomaticAuthenticate
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationScheme = "InsecureLongLived",
LoginPath = new PathString("/Account/Unauthorized/"),
AccessDeniedPath = new PathString("/Account/Forbidden/"),
AutomaticAuthenticate = true
});
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationScheme = "SecureAndShortLived",
LoginPath = new PathString("/Account/Unauthorized/"),
AccessDeniedPath = new PathString("/Account/Forbidden/"),
AutomaticAuthenticate = false
});
The default one is long lived and used for non-critical auth scenarios e.g. on Facebook, this may be to view your profile page.
The more secure and short lived on is used for security critical user actions like changing your password or profile information.
This gives you the convenience of not having to login all the time with a long lived cookie but as soon as you need to do something potentially dangerous, you switch to doing auth with a much shorter lived and thus more secure cookie which requires the user to login again.

ASP .NET Core Cookie Authentication expiration changes from timestamp to "Session" upon return

I am using ASP .NET Core RC1 with Facebook-authentication and silding window cookie expiration set up like this:
app.UseIdentity();
app.UseFacebookAuthentication();
and
services.AddIdentity<ApplicationUser, IdentityRole>((options =>
{
options.Cookies.ApplicationCookie.CookieName = "myauthcookie";
options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(5);
options.Cookies.ApplicationCookie.SlidingExpiration = true;
}))
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
This works fine when the user first logs in - the cookie expiration is set correctly. However, when the user returns to the page, the expiration of the cookie is set to "Session", so in practice the user has to re-authenticate every other visit.
Why is this happening? Have I not configured it correctly?
Update:
I have now done some testing without SlidingExpiration, and the issue remains the same. Upon returning to the page, the expiration of the cookie is changed to "Session". I am using Chrome.
Also, I am not running on https. Might this be a factor?
Short Answer
Set isPersistent: true when calling SignInManager.ExternalLoginSignInAsync.
Details
In the ASP.NET Core Web Application template, the AccountController.ExternalLoginCallback method contains this code:
_signInManager.ExternalLoginSignInAsync(
info.LoginProvider,
info.ProviderKey,
isPersistent: true); <------ set a persistent cookie.
If we set isPersistent: true when calling ExternalLoginSignInAsync , this startup configuration...
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Cookies.ApplicationCookie.CookieName = "MyApplicationCookie";
options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(5);
options.Cookies.ApplicationCookie.SlidingExpiration = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
...results in this application cookie...
...which persists across browser sessions.

Invalidate user credentials when password changes

I have an Asp.net MVC website. When the users change their password, do the logins from all of the browsers invalidate? I mean will the user require to login on all browsers with the new password? If not, is there a way to do this?
Not immediately, it will take 30 minutes by default for old cookies to invalidate in asp.net Identity 2, asp.net identity doesn't check the database on every request for that, it has an interval, use SecurityStamp to change it, you can set it in Startup.Auth.cs, default is 30 minutes, set the validateInterval to 0, this is not the most efficient approach because on every request the database will be hit to check if the cookies are still valid, but it will do the job if you want to see the effects immediately, also take a look at this and this.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromSeconds(0),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});

Resources