U4-7538 GetRemainingTimeoutSeconds is double setting the cookie in 7.4
This commit is contained in:
@@ -118,33 +118,45 @@ namespace Umbraco.Web.Security.Identity
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException("app");
|
||||
if (appContext == null) throw new ArgumentNullException("appContext");
|
||||
|
||||
|
||||
var cookieAuthProvider = new BackOfficeCookieAuthenticationProvider
|
||||
{
|
||||
// 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<BackOfficeUserManager, BackOfficeIdentityUser, int>(
|
||||
TimeSpan.FromMinutes(30),
|
||||
(manager, user) => user.GenerateUserIdentityAsync(manager),
|
||||
identity => identity.GetUserId<int>()),
|
||||
};
|
||||
|
||||
var authOptions = new UmbracoBackOfficeCookieAuthOptions(
|
||||
UmbracoConfig.For.UmbracoSettings().Security,
|
||||
GlobalSettings.TimeOutInMinutes,
|
||||
GlobalSettings.UseSSL)
|
||||
{
|
||||
Provider = new BackOfficeCookieAuthenticationProvider
|
||||
{
|
||||
// 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<BackOfficeUserManager, BackOfficeIdentityUser, int>(
|
||||
TimeSpan.FromMinutes(30),
|
||||
(manager, user) => user.GenerateUserIdentityAsync(manager),
|
||||
identity => identity.GetUserId<int>()),
|
||||
}
|
||||
Provider = cookieAuthProvider
|
||||
};
|
||||
|
||||
|
||||
app.UseUmbracoBackOfficeCookieAuthentication(authOptions, appContext);
|
||||
|
||||
//don't apply if app isnot ready
|
||||
if (appContext.IsUpgrading || appContext.IsConfigured)
|
||||
{
|
||||
var getSecondsOptions = new UmbracoBackOfficeCookieAuthOptions(
|
||||
//This defines the explicit path read cookies from for this middleware
|
||||
new[]{string.Format("{0}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds", GlobalSettings.Path)},
|
||||
UmbracoConfig.For.UmbracoSettings().Security,
|
||||
GlobalSettings.TimeOutInMinutes,
|
||||
GlobalSettings.UseSSL)
|
||||
{
|
||||
Provider = cookieAuthProvider
|
||||
};
|
||||
|
||||
//This is a custom middleware, we need to return the user's remaining logged in seconds
|
||||
app.Use<GetUserSecondsMiddleWare>(
|
||||
authOptions,
|
||||
getSecondsOptions,
|
||||
UmbracoConfig.For.UmbracoSettings().Security,
|
||||
app.CreateLogger<GetUserSecondsMiddleWare>());
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Microsoft.Owin;
|
||||
using Microsoft.Owin.Infrastructure;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Web.Security.Identity
|
||||
@@ -17,10 +20,19 @@ namespace Umbraco.Web.Security.Identity
|
||||
internal class BackOfficeCookieManager : ChunkingCookieManager, ICookieManager
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly string[] _explicitPaths;
|
||||
private readonly string _getRemainingSecondsPath;
|
||||
|
||||
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor)
|
||||
: this(umbracoContextAccessor, null)
|
||||
{
|
||||
|
||||
}
|
||||
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IEnumerable<string> explicitPaths)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_explicitPaths = explicitPaths == null ? null : explicitPaths.ToArray();
|
||||
_getRemainingSecondsPath = string.Format("{0}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds", GlobalSettings.Path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -64,9 +76,18 @@ namespace Umbraco.Web.Security.Identity
|
||||
var request = ctx.Request;
|
||||
var httpCtx = ctx.TryGetHttpContext();
|
||||
|
||||
//check the explicit paths
|
||||
if (_explicitPaths != null)
|
||||
{
|
||||
return _explicitPaths.Any(x => x.InvariantEquals(request.Uri.AbsolutePath));
|
||||
}
|
||||
|
||||
//check user seconds path
|
||||
if (request.Uri.AbsolutePath.InvariantEquals(_getRemainingSecondsPath)) return false;
|
||||
|
||||
if (//check the explicit flag
|
||||
(checkForceAuthTokens && ctx.Get<bool?>("umbraco-force-auth") != null)
|
||||
|| (checkForceAuthTokens && httpCtx.Success && httpCtx.Result.Items["umbraco-force-auth"] != null)
|
||||
|| (checkForceAuthTokens && httpCtx.Success && httpCtx.Result.Items["umbraco-force-auth"] != null)
|
||||
//check back office
|
||||
|| request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath)
|
||||
//check installer
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace Umbraco.Web.Security.Identity
|
||||
private readonly UmbracoBackOfficeCookieAuthOptions _authOptions;
|
||||
private readonly ISecuritySection _security;
|
||||
private readonly ILogger _logger;
|
||||
private const int PersistentLoginSlidingMinutes = 30;
|
||||
|
||||
public GetUserSecondsMiddleWare(
|
||||
OwinMiddleware next,
|
||||
@@ -44,14 +43,10 @@ namespace Umbraco.Web.Security.Identity
|
||||
{
|
||||
var request = context.Request;
|
||||
var response = context.Response;
|
||||
|
||||
var rootPath = context.Request.PathBase.HasValue
|
||||
? context.Request.PathBase.Value.EnsureStartsWith("/").EnsureEndsWith("/")
|
||||
: "/";
|
||||
|
||||
|
||||
if (request.Uri.Scheme.InvariantStartsWith("http")
|
||||
&& request.Uri.AbsolutePath.InvariantEquals(
|
||||
string.Format("{0}{1}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds", rootPath, GlobalSettings.UmbracoMvcArea)))
|
||||
string.Format("{0}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds", GlobalSettings.Path)))
|
||||
{
|
||||
var cookie = _authOptions.CookieManager.GetRequestCookie(context, _security.AuthCookieName);
|
||||
if (cookie.IsNullOrWhiteSpace() == false)
|
||||
@@ -88,7 +83,8 @@ namespace Umbraco.Web.Security.Identity
|
||||
if (timeRemaining < timeElapsed)
|
||||
{
|
||||
ticket.Properties.IssuedUtc = currentUtc;
|
||||
ticket.Properties.ExpiresUtc = currentUtc.AddMinutes(PersistentLoginSlidingMinutes);
|
||||
var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value);
|
||||
ticket.Properties.ExpiresUtc = currentUtc.Add(timeSpan);
|
||||
|
||||
var cookieValue = _authOptions.TicketDataFormat.Protect(ticket);
|
||||
|
||||
|
||||
@@ -21,35 +21,13 @@ namespace Umbraco.Web.Security.Identity
|
||||
: this(UmbracoConfig.For.UmbracoSettings().Security, GlobalSettings.TimeOutInMinutes, GlobalSettings.UseSSL)
|
||||
{
|
||||
}
|
||||
|
||||
public CookieOptions CreateRequestCookieOptions(IOwinContext ctx, AuthenticationTicket ticket)
|
||||
{
|
||||
if (ctx == null) throw new ArgumentNullException("ctx");
|
||||
if (ticket == null) throw new ArgumentNullException("ticket");
|
||||
|
||||
var cookieOptions = new CookieOptions
|
||||
{
|
||||
Path = "/",
|
||||
Domain = this.CookieDomain ?? null,
|
||||
Expires = DateTime.Now.AddMinutes(30),
|
||||
HttpOnly = true,
|
||||
Secure = this.CookieSecure == CookieSecureOption.Always
|
||||
|| (this.CookieSecure == CookieSecureOption.SameAsRequest && ctx.Request.IsSecure),
|
||||
};
|
||||
|
||||
if (ticket.Properties.IsPersistent && ticket.Properties.ExpiresUtc.HasValue)
|
||||
{
|
||||
cookieOptions.Expires = ticket.Properties.ExpiresUtc.Value.ToUniversalTime().DateTime;
|
||||
}
|
||||
|
||||
return cookieOptions;
|
||||
}
|
||||
|
||||
public UmbracoBackOfficeCookieAuthOptions(
|
||||
ISecuritySection securitySection,
|
||||
int loginTimeoutMinutes,
|
||||
bool forceSsl,
|
||||
bool useLegacyFormsAuthDataFormat = true)
|
||||
|
||||
public UmbracoBackOfficeCookieAuthOptions(
|
||||
string[] explicitPaths,
|
||||
ISecuritySection securitySection,
|
||||
int loginTimeoutMinutes,
|
||||
bool forceSsl,
|
||||
bool useLegacyFormsAuthDataFormat = true)
|
||||
{
|
||||
LoginTimeoutMinutes = loginTimeoutMinutes;
|
||||
AuthenticationType = Constants.Security.BackOfficeAuthenticationType;
|
||||
@@ -57,9 +35,9 @@ namespace Umbraco.Web.Security.Identity
|
||||
if (useLegacyFormsAuthDataFormat)
|
||||
{
|
||||
//If this is not explicitly set it will fall back to the default automatically
|
||||
TicketDataFormat = new FormsAuthenticationSecureDataFormat(loginTimeoutMinutes);
|
||||
TicketDataFormat = new FormsAuthenticationSecureDataFormat(loginTimeoutMinutes);
|
||||
}
|
||||
|
||||
|
||||
SlidingExpiration = true;
|
||||
ExpireTimeSpan = TimeSpan.FromMinutes(LoginTimeoutMinutes);
|
||||
CookieDomain = securitySection.AuthCookieDomain;
|
||||
@@ -69,7 +47,49 @@ namespace Umbraco.Web.Security.Identity
|
||||
CookiePath = "/";
|
||||
|
||||
//Custom cookie manager so we can filter requests
|
||||
CookieManager = new BackOfficeCookieManager(new SingletonUmbracoContextAccessor());
|
||||
}
|
||||
CookieManager = new BackOfficeCookieManager(new SingletonUmbracoContextAccessor(), explicitPaths);
|
||||
}
|
||||
|
||||
public UmbracoBackOfficeCookieAuthOptions(
|
||||
ISecuritySection securitySection,
|
||||
int loginTimeoutMinutes,
|
||||
bool forceSsl,
|
||||
bool useLegacyFormsAuthDataFormat = true)
|
||||
: this(null, securitySection, loginTimeoutMinutes, forceSsl, useLegacyFormsAuthDataFormat)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the cookie options for saving the auth cookie
|
||||
/// </summary>
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="ticket"></param>
|
||||
/// <returns></returns>
|
||||
public CookieOptions CreateRequestCookieOptions(IOwinContext ctx, AuthenticationTicket ticket)
|
||||
{
|
||||
if (ctx == null) throw new ArgumentNullException("ctx");
|
||||
if (ticket == null) throw new ArgumentNullException("ticket");
|
||||
|
||||
var issuedUtc = ticket.Properties.IssuedUtc ?? SystemClock.UtcNow;
|
||||
var expiresUtc = ticket.Properties.ExpiresUtc ?? issuedUtc.Add(ExpireTimeSpan);
|
||||
|
||||
var cookieOptions = new CookieOptions
|
||||
{
|
||||
Path = "/",
|
||||
Domain = this.CookieDomain ?? null,
|
||||
HttpOnly = true,
|
||||
Secure = this.CookieSecure == CookieSecureOption.Always
|
||||
|| (this.CookieSecure == CookieSecureOption.SameAsRequest && ctx.Request.IsSecure),
|
||||
};
|
||||
|
||||
if (ticket.Properties.IsPersistent)
|
||||
{
|
||||
cookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime;
|
||||
}
|
||||
|
||||
return cookieOptions;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user