diff --git a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
index 85578dbb99..8d99086ba5 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
@@ -56,7 +56,7 @@ angular.module('umbraco.services')
/**
Method to count down the current user's timeout seconds,
- this will continually count down their current remaining seconds every 2 seconds until
+ this will continually count down their current remaining seconds every 5 seconds until
there are no more seconds remaining.
*/
function countdownUserTimeout() {
@@ -64,8 +64,8 @@ angular.module('umbraco.services')
$timeout(function () {
if (currentUser) {
- //countdown by 2 seconds since that is how long our timer is for.
- currentUser.remainingAuthSeconds -= 2;
+ //countdown by 5 seconds since that is how long our timer is for.
+ currentUser.remainingAuthSeconds -= 5;
//if there are more than 30 remaining seconds, recurse!
if (currentUser.remainingAuthSeconds > 30) {
@@ -128,7 +128,7 @@ angular.module('umbraco.services')
}
}
}
- }, 2000, //every 2 seconds
+ }, 5000, //every 5 seconds
false); //false = do NOT execute a digest for every iteration
}
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index f51d61b15c..c2de5441ab 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -151,7 +151,29 @@
False
..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll
+
+ ..\packages\Microsoft.AspNet.Identity.Core.2.1.0\lib\net45\Microsoft.AspNet.Identity.Core.dll
+
+
+ ..\packages\Microsoft.AspNet.Identity.Owin.2.1.0\lib\net45\Microsoft.AspNet.Identity.Owin.dll
+
+
+ False
+ ..\packages\Microsoft.Owin.3.0.0\lib\net45\Microsoft.Owin.dll
+
+
+ ..\packages\Microsoft.Owin.Host.SystemWeb.3.0.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
+
+
+ ..\packages\Microsoft.Owin.Security.2.1.0\lib\net45\Microsoft.Owin.Security.dll
+
+
+ ..\packages\Microsoft.Owin.Security.Cookies.2.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll
+
+
+ ..\packages\Microsoft.Owin.Security.OAuth.2.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll
+
..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.dll
@@ -178,6 +200,9 @@
False
..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+
System
@@ -324,6 +349,7 @@
Properties\SolutionInfo.cs
+
loadStarterKits.ascx
ASPXCodeBehind
@@ -2518,7 +2544,6 @@
-
diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config
index da11256606..150759f582 100644
--- a/src/Umbraco.Web.UI/packages.config
+++ b/src/Umbraco.Web.UI/packages.config
@@ -9,6 +9,8 @@
+
+
@@ -21,10 +23,16 @@
+
+
+
+
+
+
diff --git a/src/Umbraco.Web/Security/Identity/AppBuilderExtensions.cs b/src/Umbraco.Web/Security/Identity/AppBuilderExtensions.cs
new file mode 100644
index 0000000000..f2ef0a010d
--- /dev/null
+++ b/src/Umbraco.Web/Security/Identity/AppBuilderExtensions.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Web;
+using Microsoft.AspNet.Identity.Owin;
+using Microsoft.Owin;
+using Microsoft.Owin.Extensions;
+using Owin;
+using Umbraco.Core;
+using Umbraco.Core.Configuration;
+
+namespace Umbraco.Web.Security.Identity
+{
+ public static class AppBuilderExtensions
+ {
+ /////
+ ///// Configure Identity User Manager for Umbraco
+ /////
+ /////
+ /////
+ /////
+ //public static void ConfigureUserManagerForUmbraco(this IAppBuilder app, ApplicationContext appContext)
+ // where T : UmbracoIdentityUser, new()
+ //{
+
+ // //Don't proceed if the app is not ready
+ // if (appContext.IsConfigured == false
+ // || appContext.DatabaseContext == null
+ // || appContext.DatabaseContext.IsDatabaseConfigured == false) return;
+
+ // //Configure Umbraco user manager to be created per request
+ // app.CreatePerOwinContext>(
+ // (o, c) => UmbracoMembersUserManager.Create(
+ // o, c, ApplicationContext.Current.Services.MemberService));
+
+ // //Configure Umbraco member event handler to be created per request - this will ensure that the
+ // // external logins are kept in sync if members are deleted from Umbraco
+ // app.CreatePerOwinContext>((options, context) => new MembersEventHandler(context));
+
+ // //TODO: This is just for the mem leak fix
+ // app.CreatePerOwinContext, UmbracoMembersUserManager>>(
+ // (o, c) => new OwinContextDisposal, UmbracoMembersUserManager>(c));
+ //}
+
+ ///
+ /// Ensures that the UmbracoBackOfficeAuthenticationMiddleware is assigned to the pipeline
+ ///
+ ///
+ ///
+ public static IAppBuilder UseUmbracoBackAuthentication(this IAppBuilder app)
+ {
+ if (app == null) throw new ArgumentNullException("app");
+
+ app.Use(typeof (UmbracoBackOfficeAuthenticationMiddleware),
+ //ctor params
+ app, new UmbracoBackOfficeAuthenticationOptions(), UmbracoConfig.For.UmbracoSettings().Security);
+
+ app.UseStageMarker(PipelineStage.Authenticate);
+ return app;
+ }
+
+ //This is a fix for OWIN mem leak!
+ //http://stackoverflow.com/questions/24378856/memory-leak-in-owin-appbuilderextensions/24819543#24819543
+ private class OwinContextDisposal : IDisposable
+ where T1 : IDisposable
+ where T2 : IDisposable
+ {
+ private readonly List _disposables = new List();
+ private bool _disposed = false;
+
+ public OwinContextDisposal(IOwinContext owinContext)
+ {
+ if (HttpContext.Current == null) return;
+
+ _disposables.Add(owinContext.Get());
+ _disposables.Add(owinContext.Get());
+
+ HttpContext.Current.DisposeOnPipelineCompleted(this);
+ }
+
+ public void Dispose()
+ {
+ if (_disposed) return;
+ foreach (var disposable in _disposables)
+ {
+ disposable.Dispose();
+ }
+ _disposed = true;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Security/Identity/OwinExtensions.cs b/src/Umbraco.Web/Security/Identity/OwinExtensions.cs
new file mode 100644
index 0000000000..4b83f97bd3
--- /dev/null
+++ b/src/Umbraco.Web/Security/Identity/OwinExtensions.cs
@@ -0,0 +1,19 @@
+using System.Web;
+using Microsoft.Owin;
+
+namespace Umbraco.Web.Security.Identity
+{
+ internal static class OwinExtensions
+ {
+ ///
+ /// Nasty little hack to get httpcontextbase from an owin context
+ ///
+ ///
+ ///
+ public static HttpContextBase HttpContextFromOwinContext(this IOwinContext owinContext)
+ {
+ return owinContext.Get(typeof(HttpContextBase).FullName);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationHandler.cs b/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationHandler.cs
new file mode 100644
index 0000000000..1b0adc604c
--- /dev/null
+++ b/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationHandler.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Web.Security;
+using Microsoft.Owin;
+using Microsoft.Owin.Security;
+using Microsoft.Owin.Security.Infrastructure;
+using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core.Security;
+using Umbraco.Core;
+
+namespace Umbraco.Web.Security.Identity
+{
+ ///
+ /// Used to allow normal Umbraco back office authentication to work
+ ///
+ public class UmbracoBackOfficeAuthenticationHandler : AuthenticationHandler
+ {
+ private readonly ISecuritySection _securitySection;
+
+ public UmbracoBackOfficeAuthenticationHandler(ISecuritySection securitySection)
+ {
+ _securitySection = securitySection;
+ }
+
+ ///
+ /// Checks if we should authentication the request (i.e. is back office) and if so gets the forms auth ticket in the request
+ /// and returns an AuthenticationTicket based on that.
+ ///
+ ///
+ ///
+ /// It's worth noting that the UmbracoModule still executes and performs the authentication, however this also needs to execute
+ /// so that it assigns the new Principal object on the OWIN request:
+ /// http://brockallen.com/2013/10/27/host-authentication-and-web-api-with-owin-and-active-vs-passive-authentication-middleware/
+ ///
+ protected override Task AuthenticateCoreAsync()
+ {
+ if (ShouldAuthRequest())
+ {
+ var authTicket = GetAuthTicket(Request, _securitySection.AuthCookieName);
+ if (authTicket != null)
+ {
+ return Task.FromResult(new AuthenticationTicket(new UmbracoBackOfficeIdentity(authTicket), new AuthenticationProperties()));
+ }
+ }
+
+ return Task.FromResult(null);
+ }
+
+ private bool ShouldAuthRequest()
+ {
+ var httpContext = Context.HttpContextFromOwinContext();
+
+ // do not process if client-side request
+ if (httpContext.Request.Url.IsClientSideRequest())
+ return false;
+
+ return UmbracoModule.ShouldAuthenticateRequest(httpContext.Request, Request.Uri);
+ }
+
+ ///
+ /// Returns the current FormsAuth ticket in the request
+ ///
+ ///
+ ///
+ ///
+ private static FormsAuthenticationTicket GetAuthTicket(IOwinRequest request, string cookieName)
+ {
+ if (request == null) throw new ArgumentNullException("request");
+
+ var formsCookie = request.Cookies[cookieName];
+ if (formsCookie == null)
+ {
+ return null;
+ }
+ //get the ticket
+ try
+ {
+ return FormsAuthentication.Decrypt(formsCookie);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationMiddleware.cs b/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationMiddleware.cs
new file mode 100644
index 0000000000..1275b72c08
--- /dev/null
+++ b/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationMiddleware.cs
@@ -0,0 +1,26 @@
+using Microsoft.Owin;
+using Microsoft.Owin.Security.Infrastructure;
+using Owin;
+using Umbraco.Core.Configuration.UmbracoSettings;
+
+namespace Umbraco.Web.Security.Identity
+{
+ ///
+ /// Used to enable the normal Umbraco back office authentication to operate
+ ///
+ public class UmbracoBackOfficeAuthenticationMiddleware : AuthenticationMiddleware
+ {
+ private readonly ISecuritySection _securitySection;
+
+ public UmbracoBackOfficeAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, UmbracoBackOfficeAuthenticationOptions options, ISecuritySection securitySection)
+ : base(next, options)
+ {
+ _securitySection = securitySection;
+ }
+
+ protected override AuthenticationHandler CreateHandler()
+ {
+ return new UmbracoBackOfficeAuthenticationHandler(_securitySection);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationOptions.cs b/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationOptions.cs
new file mode 100644
index 0000000000..c7609a8e83
--- /dev/null
+++ b/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeAuthenticationOptions.cs
@@ -0,0 +1,18 @@
+using Microsoft.Owin.Security;
+
+namespace Umbraco.Web.Security.Identity
+{
+ ///
+ /// Umbraco auth options - really just ensures that it is operating in Active mode
+ ///
+ public sealed class UmbracoBackOfficeAuthenticationOptions : AuthenticationOptions
+ {
+ public UmbracoBackOfficeAuthenticationOptions()
+ : base("UmbracoBackOffice")
+ {
+ //Must be active, this needs to look at each request to determine if it should execute,
+ // if set to passive this will not be the case
+ AuthenticationMode = AuthenticationMode.Active;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index e261c048d3..45e0ce5fe2 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -131,7 +131,25 @@
False
..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll
+
+ ..\packages\Microsoft.AspNet.Identity.Core.2.1.0\lib\net45\Microsoft.AspNet.Identity.Core.dll
+
+
+ ..\packages\Microsoft.AspNet.Identity.Owin.2.1.0\lib\net45\Microsoft.AspNet.Identity.Owin.dll
+
+
+ ..\packages\Microsoft.Owin.2.1.0\lib\net45\Microsoft.Owin.dll
+
+
+ ..\packages\Microsoft.Owin.Security.2.1.0\lib\net45\Microsoft.Owin.Security.dll
+
+
+ ..\packages\Microsoft.Owin.Security.Cookies.2.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll
+
+
+ ..\packages\Microsoft.Owin.Security.OAuth.2.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll
+
True
..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
@@ -148,6 +166,9 @@
False
..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+
System
@@ -518,6 +539,11 @@
+
+
+
+
+
diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config
index 294079e830..3fade0702d 100644
--- a/src/Umbraco.Web/packages.config
+++ b/src/Umbraco.Web/packages.config
@@ -6,6 +6,8 @@
+
+
@@ -17,9 +19,14 @@
+
+
+
+
+