Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 64dac39bae | |||
| 6040d149ec | |||
| bfbc6595fb | |||
| 25d8fc7a13 | |||
| e11b5c3fdb | |||
| 87100feb3d | |||
| eae74b0e20 | |||
| 610efe552d | |||
| c4860a490f | |||
| 8e6bbc3df9 | |||
| c16d0b77c2 |
@@ -1,2 +1,2 @@
|
||||
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
|
||||
7.3.2
|
||||
7.3.3
|
||||
+2
-2
@@ -11,5 +11,5 @@ using System.Resources;
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyFileVersion("7.3.1")]
|
||||
[assembly: AssemblyInformationalVersion("7.3.1")]
|
||||
[assembly: AssemblyFileVersion("7.3.3")]
|
||||
[assembly: AssemblyInformationalVersion("7.3.3")]
|
||||
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.3.2");
|
||||
private static readonly Version Version = new Version("7.3.3");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
|
||||
@@ -560,8 +560,7 @@ namespace Umbraco.Core.Models
|
||||
//Additional thumbnails configured as prevalues on the DataType
|
||||
if (thumbnailSizes != null)
|
||||
{
|
||||
var sep = (thumbnailSizes.Contains("") == false && thumbnailSizes.Contains(",")) ? ',' : ';';
|
||||
foreach (var thumb in thumbnailSizes.Split(sep))
|
||||
foreach (var thumb in thumbnailSizes.Split(new[] { ";", "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
int thumbSize;
|
||||
if (thumb != "" && int.TryParse(thumb, out thumbSize))
|
||||
|
||||
+13
-13
@@ -28,37 +28,38 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne
|
||||
{
|
||||
if (database != null)
|
||||
{
|
||||
//Fetch all PropertyTypes that belongs to a PropertyTypeGroup
|
||||
//Fetch all PropertyTypes that belongs to a PropertyTypeGroup
|
||||
//NOTE: We are writing the full query because we've added a column to the PropertyTypeDto in later versions so one of the columns
|
||||
// won't exist yet
|
||||
var propertyTypes = database.Fetch<PropertyTypeDto>("SELECT * FROM cmsPropertyType WHERE propertyTypeGroupId > 0");
|
||||
//NOTE: We're using dynamic to avoid having this migration fail due to the UniqueId column added in 7.3 (this column is not added
|
||||
// in the table yet and will make the mapping of done by Fetch fail when the actual type is used here).
|
||||
var propertyTypes = database.Fetch<dynamic>("SELECT * FROM cmsPropertyType WHERE propertyTypeGroupId > 0");
|
||||
|
||||
var propertyGroups = database.Fetch<PropertyTypeGroupDto>("WHERE id > 0");
|
||||
|
||||
foreach (var propertyType in propertyTypes)
|
||||
{
|
||||
//Get the PropertyTypeGroup that the current PropertyType references
|
||||
var parentPropertyTypeGroup = propertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyTypeGroupId);
|
||||
var parentPropertyTypeGroup = propertyGroups.FirstOrDefault(x => x.Id == propertyType.propertyTypeGroupId);
|
||||
if (parentPropertyTypeGroup != null)
|
||||
{
|
||||
//If the ContentType is the same on the PropertyType and the PropertyTypeGroup the group is valid and we skip to the next
|
||||
if (parentPropertyTypeGroup.ContentTypeNodeId == propertyType.ContentTypeId) continue;
|
||||
if (parentPropertyTypeGroup.ContentTypeNodeId == propertyType.contentTypeId) continue;
|
||||
|
||||
//Check if the 'new' PropertyTypeGroup has already been created
|
||||
var existingPropertyTypeGroup =
|
||||
propertyGroups.FirstOrDefault(
|
||||
x =>
|
||||
x.ParentGroupId == parentPropertyTypeGroup.Id && x.Text == parentPropertyTypeGroup.Text &&
|
||||
x.ContentTypeNodeId == propertyType.ContentTypeId);
|
||||
x.ContentTypeNodeId == propertyType.contentTypeId);
|
||||
|
||||
//This should ensure that we don't create duplicate groups for a single ContentType
|
||||
if (existingPropertyTypeGroup == null)
|
||||
{
|
||||
|
||||
//Create a new PropertyTypeGroup that references the parent group that the PropertyType was referencing pre-6.0.1
|
||||
var propertyGroup = new PropertyTypeGroupDto
|
||||
{
|
||||
ContentTypeNodeId = propertyType.ContentTypeId,
|
||||
ContentTypeNodeId = propertyType.contentTypeId,
|
||||
ParentGroupId = parentPropertyTypeGroup.Id,
|
||||
Text = parentPropertyTypeGroup.Text,
|
||||
SortOrder = parentPropertyTypeGroup.SortOrder
|
||||
@@ -69,19 +70,18 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne
|
||||
propertyGroup.Id = id;
|
||||
propertyGroups.Add(propertyGroup);
|
||||
//Update the reference to the new PropertyTypeGroup on the current PropertyType
|
||||
propertyType.PropertyTypeGroupId = id;
|
||||
database.Update(propertyType);
|
||||
propertyType.propertyTypeGroupId = id;
|
||||
database.Update("cmsPropertyType", "id", propertyType);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Update the reference to the existing PropertyTypeGroup on the current PropertyType
|
||||
propertyType.PropertyTypeGroupId = existingPropertyTypeGroup.Id;
|
||||
database.Update(propertyType);
|
||||
//Update the reference to the existing PropertyTypeGroup on the current PropertyType
|
||||
propertyType.propertyTypeGroupId = existingPropertyTypeGroup.Id;
|
||||
database.Update("cmsPropertyType", "id", propertyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<UseIISExpress>true</UseIISExpress>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressSSLPort>
|
||||
</IISExpressSSLPort>
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
@@ -2412,9 +2413,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\"
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>7310</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>7330</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:7320</IISUrl>
|
||||
<IISUrl>http://localhost:7330</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
|
||||
@@ -137,8 +137,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
var thumbnailSizes = thumbs.First().Value.Value;
|
||||
// additional thumbnails configured as prevalues on the DataType
|
||||
var sep = (thumbnailSizes.Contains("") == false && thumbnailSizes.Contains(",")) ? ',' : ';';
|
||||
foreach (var thumb in thumbnailSizes.Split(sep))
|
||||
foreach (var thumb in thumbnailSizes.Split(new[] { ";", "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
int thumbSize;
|
||||
if (thumb == "" || int.TryParse(thumb, out thumbSize) == false) continue;
|
||||
|
||||
@@ -47,9 +47,6 @@ namespace Umbraco.Web.Security.Identity
|
||||
if (appContext == null) throw new ArgumentNullException("appContext");
|
||||
if (userMembershipProvider == null) throw new ArgumentNullException("userMembershipProvider");
|
||||
|
||||
//Don't proceed if the app is not ready
|
||||
if (appContext.IsUpgrading == false && appContext.IsConfigured == false) return;
|
||||
|
||||
//Configure Umbraco user manager to be created per request
|
||||
app.CreatePerOwinContext<BackOfficeUserManager>(
|
||||
(options, owinContext) => BackOfficeUserManager.Create(
|
||||
@@ -78,9 +75,6 @@ namespace Umbraco.Web.Security.Identity
|
||||
if (userMembershipProvider == null) throw new ArgumentNullException("userMembershipProvider");
|
||||
if (customUserStore == null) throw new ArgumentNullException("customUserStore");
|
||||
|
||||
//Don't proceed if the app is not ready
|
||||
if (appContext.IsUpgrading == false && appContext.IsConfigured == false) return;
|
||||
|
||||
//Configure Umbraco user manager to be created per request
|
||||
app.CreatePerOwinContext<BackOfficeUserManager>(
|
||||
(options, owinContext) => BackOfficeUserManager.Create(
|
||||
@@ -107,9 +101,6 @@ namespace Umbraco.Web.Security.Identity
|
||||
if (appContext == null) throw new ArgumentNullException("appContext");
|
||||
if (userManager == null) throw new ArgumentNullException("userManager");
|
||||
|
||||
//Don't proceed if the app is not ready
|
||||
if (appContext.IsUpgrading == false && appContext.IsConfigured == false) return;
|
||||
|
||||
//Configure Umbraco user manager to be created per request
|
||||
app.CreatePerOwinContext<TManager>(userManager);
|
||||
|
||||
@@ -127,10 +118,7 @@ namespace Umbraco.Web.Security.Identity
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException("app");
|
||||
if (appContext == null) throw new ArgumentNullException("appContext");
|
||||
|
||||
//Don't proceed if the app is not ready
|
||||
if (appContext.IsUpgrading == false && appContext.IsConfigured == false) return app;
|
||||
|
||||
|
||||
var authOptions = new UmbracoBackOfficeCookieAuthOptions(
|
||||
UmbracoConfig.For.UmbracoSettings().Security,
|
||||
GlobalSettings.TimeOutInMinutes,
|
||||
@@ -148,19 +136,23 @@ namespace Umbraco.Web.Security.Identity
|
||||
identity => identity.GetUserId<int>()),
|
||||
}
|
||||
};
|
||||
|
||||
app.UseUmbracoBackOfficeCookieAuthentication(authOptions, appContext);
|
||||
|
||||
//This is a custom middleware, we need to return the user's remaining logged in seconds
|
||||
app.Use<GetUserSecondsMiddleWare>(
|
||||
authOptions,
|
||||
UmbracoConfig.For.UmbracoSettings().Security,
|
||||
app.CreateLogger<GetUserSecondsMiddleWare>());
|
||||
|
||||
app.UseUmbracoBackOfficeCookieAuthentication(authOptions);
|
||||
//don't apply if app isnot ready
|
||||
if (appContext.IsUpgrading || appContext.IsConfigured)
|
||||
{
|
||||
//This is a custom middleware, we need to return the user's remaining logged in seconds
|
||||
app.Use<GetUserSecondsMiddleWare>(
|
||||
authOptions,
|
||||
UmbracoConfig.For.UmbracoSettings().Security,
|
||||
app.CreateLogger<GetUserSecondsMiddleWare>());
|
||||
}
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
internal static IAppBuilder UseUmbracoBackOfficeCookieAuthentication(this IAppBuilder app, CookieAuthenticationOptions options)
|
||||
internal static IAppBuilder UseUmbracoBackOfficeCookieAuthentication(this IAppBuilder app, CookieAuthenticationOptions options, ApplicationContext appContext)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
@@ -170,12 +162,17 @@ namespace Umbraco.Web.Security.Identity
|
||||
//First the normal cookie middleware
|
||||
app.Use(typeof(CookieAuthenticationMiddleware), app, options);
|
||||
app.UseStageMarker(PipelineStage.Authenticate);
|
||||
|
||||
//don't apply if app isnot ready
|
||||
if (appContext.IsUpgrading || appContext.IsConfigured)
|
||||
{
|
||||
//Then our custom middlewares
|
||||
app.Use(typeof(ForceRenewalCookieAuthenticationMiddleware), app, options, new SingletonUmbracoContextAccessor());
|
||||
app.UseStageMarker(PipelineStage.Authenticate);
|
||||
app.Use(typeof(FixWindowsAuthMiddlware));
|
||||
app.UseStageMarker(PipelineStage.Authenticate);
|
||||
}
|
||||
|
||||
//Then our custom middlewares
|
||||
app.Use(typeof(ForceRenewalCookieAuthenticationMiddleware), app, options);
|
||||
app.UseStageMarker(PipelineStage.Authenticate);
|
||||
app.Use(typeof(FixWindowsAuthMiddlware));
|
||||
app.UseStageMarker(PipelineStage.Authenticate);
|
||||
|
||||
return app;
|
||||
}
|
||||
@@ -192,9 +189,6 @@ namespace Umbraco.Web.Security.Identity
|
||||
if (app == null) throw new ArgumentNullException("app");
|
||||
if (appContext == null) throw new ArgumentNullException("appContext");
|
||||
|
||||
//Don't proceed if the app is not ready
|
||||
if (appContext.IsUpgrading == false && appContext.IsConfigured == false) return app;
|
||||
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions
|
||||
{
|
||||
AuthenticationType = Constants.Security.BackOfficeExternalAuthenticationType,
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace Umbraco.Web.Security.Identity
|
||||
/// </summary>
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="originalRequestUrl"></param>
|
||||
/// <param name="checkForceAuthTokens"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// We auth the request when:
|
||||
@@ -58,14 +59,14 @@ namespace Umbraco.Web.Security.Identity
|
||||
/// * it is a /base request
|
||||
/// * it is a preview request
|
||||
/// </remarks>
|
||||
internal static bool ShouldAuthenticateRequest(IOwinContext ctx, Uri originalRequestUrl)
|
||||
internal bool ShouldAuthenticateRequest(IOwinContext ctx, Uri originalRequestUrl, bool checkForceAuthTokens = true)
|
||||
{
|
||||
var request = ctx.Request;
|
||||
var httpCtx = ctx.TryGetHttpContext();
|
||||
|
||||
if (//check the explicit flag
|
||||
ctx.Get<bool?>("umbraco-force-auth") != null
|
||||
|| (httpCtx.Success && httpCtx.Result.Items["umbraco-force-auth"] != null)
|
||||
(checkForceAuthTokens && ctx.Get<bool?>("umbraco-force-auth") != null)
|
||||
|| (checkForceAuthTokens && httpCtx.Success && httpCtx.Result.Items["umbraco-force-auth"] != null)
|
||||
//check back office
|
||||
|| request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath)
|
||||
//check installer
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Owin;
|
||||
using Microsoft.Owin.Security;
|
||||
@@ -11,6 +13,13 @@ namespace Umbraco.Web.Security.Identity
|
||||
/// </summary>
|
||||
internal class ForceRenewalCookieAuthenticationHandler : AuthenticationHandler<CookieAuthenticationOptions>
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
|
||||
public ForceRenewalCookieAuthenticationHandler(IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This handler doesn't actually do any auth so we return null;
|
||||
/// </summary>
|
||||
@@ -45,7 +54,20 @@ namespace Umbraco.Web.Security.Identity
|
||||
/// <returns></returns>
|
||||
protected override Task ApplyResponseGrantAsync()
|
||||
{
|
||||
//Now we need to check if we should force renew this based on a flag in the context
|
||||
if (_umbracoContextAccessor.Value == null || Context.Request.Uri.IsClientSideRequest())
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
//Now we need to check if we should force renew this based on a flag in the context and whether this is a request that is not normally renewed by OWIN...
|
||||
// which means that it is not a normal URL that is authenticated.
|
||||
|
||||
var normalAuthUrl = ((BackOfficeCookieManager) Options.CookieManager)
|
||||
.ShouldAuthenticateRequest(Context, _umbracoContextAccessor.Value.OriginalRequestUrl,
|
||||
//Pass in false, we want to know if this is a normal auth'd page
|
||||
checkForceAuthTokens: false);
|
||||
//This is auth'd normally, so OWIN will naturally take care of the cookie renewal
|
||||
if (normalAuthUrl) return Task.FromResult(0);
|
||||
|
||||
var httpCtx = Context.TryGetHttpContext();
|
||||
//check for the special flag in either the owin or http context
|
||||
@@ -62,45 +84,39 @@ namespace Umbraco.Web.Security.Identity
|
||||
if (shouldSignin == false && shouldSignout == false)
|
||||
{
|
||||
//get the ticket
|
||||
var model = GetTicket();
|
||||
if (model != null)
|
||||
var ticket = GetTicket();
|
||||
if (ticket != null)
|
||||
{
|
||||
var currentUtc = Options.SystemClock.UtcNow;
|
||||
var issuedUtc = model.Properties.IssuedUtc;
|
||||
var expiresUtc = model.Properties.ExpiresUtc;
|
||||
var issuedUtc = ticket.Properties.IssuedUtc;
|
||||
var expiresUtc = ticket.Properties.ExpiresUtc;
|
||||
|
||||
if (expiresUtc.HasValue && issuedUtc.HasValue)
|
||||
{
|
||||
//renew the date/times
|
||||
model.Properties.IssuedUtc = currentUtc;
|
||||
var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value);
|
||||
model.Properties.ExpiresUtc = currentUtc.Add(timeSpan);
|
||||
var timeElapsed = currentUtc.Subtract(issuedUtc.Value);
|
||||
var timeRemaining = expiresUtc.Value.Subtract(currentUtc);
|
||||
|
||||
//now save back all the required cookie details
|
||||
var cookieValue = Options.TicketDataFormat.Protect(model);
|
||||
var cookieOptions = new CookieOptions
|
||||
//if it's time to renew, then do it
|
||||
if (timeRemaining < timeElapsed)
|
||||
{
|
||||
Domain = Options.CookieDomain,
|
||||
HttpOnly = Options.CookieHttpOnly,
|
||||
Path = Options.CookiePath ?? "/",
|
||||
};
|
||||
if (Options.CookieSecure == CookieSecureOption.SameAsRequest)
|
||||
{
|
||||
cookieOptions.Secure = Request.IsSecure;
|
||||
}
|
||||
else
|
||||
{
|
||||
cookieOptions.Secure = Options.CookieSecure == CookieSecureOption.Always;
|
||||
}
|
||||
if (model.Properties.IsPersistent)
|
||||
{
|
||||
cookieOptions.Expires = model.Properties.ExpiresUtc.Value.ToUniversalTime().DateTime;
|
||||
}
|
||||
Options.CookieManager.AppendResponseCookie(
|
||||
Context,
|
||||
Options.CookieName,
|
||||
cookieValue,
|
||||
cookieOptions);
|
||||
//renew the date/times
|
||||
ticket.Properties.IssuedUtc = currentUtc;
|
||||
var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value);
|
||||
ticket.Properties.ExpiresUtc = currentUtc.Add(timeSpan);
|
||||
|
||||
//now save back all the required cookie details
|
||||
var cookieValue = Options.TicketDataFormat.Protect(ticket);
|
||||
|
||||
var cookieOptions = ((UmbracoBackOfficeCookieAuthOptions)Options).CreateRequestCookieOptions(Context, ticket);
|
||||
|
||||
Options.CookieManager.AppendResponseCookie(
|
||||
Context,
|
||||
Options.CookieName,
|
||||
cookieValue,
|
||||
cookieOptions);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,20 @@ namespace Umbraco.Web.Security.Identity
|
||||
/// </summary>
|
||||
internal class ForceRenewalCookieAuthenticationMiddleware : CookieAuthenticationMiddleware
|
||||
{
|
||||
public ForceRenewalCookieAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, CookieAuthenticationOptions options) : base(next, app, options)
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
|
||||
public ForceRenewalCookieAuthenticationMiddleware(
|
||||
OwinMiddleware next,
|
||||
IAppBuilder app,
|
||||
UmbracoBackOfficeCookieAuthOptions options,
|
||||
IUmbracoContextAccessor umbracoContextAccessor) : base(next, app, options)
|
||||
{
|
||||
}
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
}
|
||||
|
||||
protected override AuthenticationHandler<CookieAuthenticationOptions> CreateHandler()
|
||||
{
|
||||
return new ForceRenewalCookieAuthenticationHandler();
|
||||
return new ForceRenewalCookieAuthenticationHandler(_umbracoContextAccessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ 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,
|
||||
@@ -59,7 +60,7 @@ namespace Umbraco.Web.Security.Identity
|
||||
if (ticket != null)
|
||||
{
|
||||
var remainingSeconds = ticket.Properties.ExpiresUtc.HasValue
|
||||
? (ticket.Properties.ExpiresUtc.Value - DateTime.Now.ToUniversalTime()).TotalSeconds
|
||||
? (ticket.Properties.ExpiresUtc.Value - _authOptions.SystemClock.UtcNow).TotalSeconds
|
||||
: 0;
|
||||
|
||||
response.ContentType = "application/json; charset=utf-8";
|
||||
@@ -67,36 +68,41 @@ namespace Umbraco.Web.Security.Identity
|
||||
response.Headers.Add("Cache-Control", new[] { "no-cache" });
|
||||
response.Headers.Add("Pragma", new[] { "no-cache" });
|
||||
response.Headers.Add("Expires", new[] { "-1" });
|
||||
response.Headers.Add("Date", new[] { DateTime.Now.ToUniversalTime().ToString("R") });
|
||||
response.Headers.Add("Date", new[] { _authOptions.SystemClock.UtcNow.ToString("R") });
|
||||
|
||||
//Ok, so here we need to check if we want to process/renew the auth ticket for each
|
||||
// of these requests. If that is the case, the user will really never be logged out until they
|
||||
// close their browser (there will be edge cases of that, especially when debugging)
|
||||
if (_security.KeepUserLoggedIn)
|
||||
{
|
||||
var utcNow = DateTime.Now.ToUniversalTime();
|
||||
ticket.Properties.IssuedUtc = utcNow;
|
||||
ticket.Properties.ExpiresUtc = utcNow.AddMinutes(30);
|
||||
var currentUtc = _authOptions.SystemClock.UtcNow;
|
||||
var issuedUtc = ticket.Properties.IssuedUtc;
|
||||
var expiresUtc = ticket.Properties.ExpiresUtc;
|
||||
|
||||
var cookieValue = _authOptions.TicketDataFormat.Protect(ticket);
|
||||
|
||||
var cookieOptions = new CookieOptions
|
||||
if (expiresUtc.HasValue && issuedUtc.HasValue)
|
||||
{
|
||||
Path = "/",
|
||||
Domain = _authOptions.CookieDomain ?? null,
|
||||
Expires = DateTime.Now.AddMinutes(30),
|
||||
HttpOnly = true,
|
||||
Secure = _authOptions.CookieSecure == CookieSecureOption.Always
|
||||
|| (_authOptions.CookieSecure == CookieSecureOption.SameAsRequest && request.Uri.Scheme.InvariantEquals("https")),
|
||||
};
|
||||
var timeElapsed = currentUtc.Subtract(issuedUtc.Value);
|
||||
var timeRemaining = expiresUtc.Value.Subtract(currentUtc);
|
||||
|
||||
_authOptions.CookieManager.AppendResponseCookie(
|
||||
context,
|
||||
_authOptions.CookieName,
|
||||
cookieValue,
|
||||
cookieOptions);
|
||||
//if it's time to renew, then do it
|
||||
if (timeRemaining < timeElapsed)
|
||||
{
|
||||
ticket.Properties.IssuedUtc = currentUtc;
|
||||
ticket.Properties.ExpiresUtc = currentUtc.AddMinutes(PersistentLoginSlidingMinutes);
|
||||
|
||||
remainingSeconds = (ticket.Properties.ExpiresUtc.Value - DateTime.Now.ToUniversalTime()).TotalSeconds;
|
||||
var cookieValue = _authOptions.TicketDataFormat.Protect(ticket);
|
||||
|
||||
var cookieOptions = _authOptions.CreateRequestCookieOptions(context, ticket);
|
||||
|
||||
_authOptions.CookieManager.AppendResponseCookie(
|
||||
context,
|
||||
_authOptions.CookieName,
|
||||
cookieValue,
|
||||
cookieOptions);
|
||||
|
||||
remainingSeconds = (ticket.Properties.ExpiresUtc.Value - currentUtc).TotalSeconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (remainingSeconds <= 30)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Owin;
|
||||
using Microsoft.Owin.Security;
|
||||
using Microsoft.Owin.Security.Cookies;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -20,6 +22,29 @@ namespace Umbraco.Web.Security.Identity
|
||||
{
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
@@ -114,7 +114,10 @@ namespace Umbraco.Web.WebServices
|
||||
names.Add(name);
|
||||
var domain = domains.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name));
|
||||
if (domain != null)
|
||||
{
|
||||
domain.LanguageId = language.Id;
|
||||
Services.DomainService.Save(domain);
|
||||
}
|
||||
else if (Services.DomainService.Exists(domainModel.Name))
|
||||
{
|
||||
domainModel.Duplicate = true;
|
||||
|
||||
@@ -89,9 +89,7 @@ namespace umbraco.cms.businesslogic.datatype
|
||||
// additional thumbnails configured as prevalues on the DataType
|
||||
if (_thumbnailSizes != "")
|
||||
{
|
||||
char sep = (_thumbnailSizes.Contains("") == false && _thumbnailSizes.Contains(",")) ? ',' : ';';
|
||||
|
||||
foreach (string thumb in _thumbnailSizes.Split(sep))
|
||||
foreach (var thumb in _thumbnailSizes.Split(new[] { ";", "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
int thumbSize;
|
||||
if (thumb != "" && int.TryParse(thumb, out thumbSize))
|
||||
|
||||
Reference in New Issue
Block a user