diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index 4ed5027539..9292fd21e9 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using System.Web; using System.Web.Caching; +using System.Web.Security; using System.Xml; using System.Configuration; @@ -299,6 +300,32 @@ namespace Umbraco.Core.Configuration } } + internal static string AuthCookieName + { + get + { + var value = GetKey("/settings/security/authCookieName"); + if (string.IsNullOrEmpty(value) == false) + { + return value; + } + return "UMB_UCONTEXT"; + } + } + + internal static string AuthCookieDomain + { + get + { + var value = GetKey("/settings/security/authCookieDomain"); + if (string.IsNullOrEmpty(value) == false) + { + return value; + } + return FormsAuthentication.CookieDomain; + } + } + /// /// Enables the experimental canvas (live) editing on the frontend of the website /// diff --git a/src/Umbraco.Core/Security/AuthenticationExtensions.cs b/src/Umbraco.Core/Security/AuthenticationExtensions.cs new file mode 100644 index 0000000000..87d09aecf5 --- /dev/null +++ b/src/Umbraco.Core/Security/AuthenticationExtensions.cs @@ -0,0 +1,199 @@ +using System; +using System.Web; +using System.Web.Security; +using Newtonsoft.Json; +using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; + +namespace Umbraco.Core.Security +{ + internal static class FormsAuthenticationTicketExtensions + { + public static UmbracoBackOfficeIdentity CreateUmbracoIdentity(this FormsAuthenticationTicket ticket) + { + try + { + //create the Umbraco user identity + return new UmbracoBackOfficeIdentity(ticket); + } + catch (Exception ex) + { + //This might occur if we cannot decrypt the value in which case we'll just ignore it, it will + // be handled by the base pages + LogHelper.Error(typeof(FormsAuthenticationTicketExtensions), "An error occurred decrypting the user's ticket", ex); + return null; + } + } + } + + /// + /// Extensions to create and renew and remove authentication tickets for the Umbraco back office + /// + internal static class AuthenticationExtensions + { + //public static UmbracoBackOfficeIdentity GetCurrentIdentity(this HttpContextBase http) + //{ + // return http.User.Identity as UmbracoBackOfficeIdentity; + //} + + //internal static UmbracoBackOfficeIdentity GetCurrentIdentity(this HttpContext http) + //{ + // return new HttpContextWrapper(http).GetCurrentIdentity(); + //} + + /// + /// This clears the authentication cookie + /// + public static void UmbracoLogout(this HttpContextBase http) + { + Logout(http, UmbracoSettings.AuthCookieName); + } + + internal static void UmbracoLogout(this HttpContext http) + { + new HttpContextWrapper(http).UmbracoLogout(); + } + + /// + /// Creates the umbraco authentication ticket + /// + /// + /// + public static void CreateUmbracoAuthTicket(this HttpContextBase http, UserData userdata) + { + CreateAuthTicket( + http, + userdata, + //This is one full day... this is how Umbraco has always created this cookie, it is setup to always + //expire one day from issue and it never gets updated. + 1440, + "/", + UmbracoSettings.AuthCookieName, + UmbracoSettings.AuthCookieDomain); + } + + internal static void CreateUmbracoAuthTicket(this HttpContext http, UserData userdata) + { + new HttpContextWrapper(http).CreateUmbracoAuthTicket(userdata); + } + + /// + /// Gets the umbraco auth ticket + /// + /// + /// + public static FormsAuthenticationTicket GetUmbracoAuthTicket(this HttpContextBase http) + { + return GetAuthTicket(http, UmbracoSettings.AuthCookieName); + } + + internal static FormsAuthenticationTicket GetUmbracoAuthTicket(this HttpContext http) + { + return new HttpContextWrapper(http).GetUmbracoAuthTicket(); + } + + /// + /// This clears the authentication cookie + /// + /// + /// + private static void Logout(this HttpContextBase http, string cookieName) + { + //remove from the request + http.Request.Cookies.Remove(cookieName); + + //expire from the response + var formsCookie = http.Response.Cookies[cookieName]; + if (formsCookie != null) + { + //this will expire immediately and be removed from the browser + formsCookie.Expires = DateTime.Now.AddYears(-1); + } + else + { + //ensure there's def an expired cookie + http.Response.Cookies.Add(new HttpCookie(cookieName) { Expires = DateTime.Now.AddYears(-1) }); + } + } + + /// + /// In v6 this is a custom cookie, in v7 this is a real formsauth cookie. + /// + /// + /// + /// + private static FormsAuthenticationTicket GetAuthTicket(this HttpContextBase http, string cookieName) + { + var formsCookie = http.Request.Cookies[cookieName]; + if (formsCookie == null) + { + return null; + } + + try + { + //get the cookie value + var cookieVal = formsCookie.Value.DecryptWithMachineKey(); + + //here we need to see if the cookie val can be serialized into UserData, if not it means it's probably an old cookie + var deserialized = JsonConvert.DeserializeObject(cookieVal); + + //in v6, we're not using real FormsAuth but our own custom cookie and then we just return a custom FormsAuth ticket + // for this request. + return new FormsAuthenticationTicket( + 4, + deserialized.RealName, + DateTime.Now, + DateTime.Now.AddMinutes(GlobalSettings.TimeOutInMinutes), + false, + cookieVal, + "/"); + + } + catch (Exception) + { + //occurs when decryption fails + http.Logout(cookieName); + return null; + } + } + + /// + /// Creates a custom umbraco auth cookie with the data specified + /// + /// The HTTP. + /// The user data. + /// The minutes persisted. + /// The cookie path. + /// Name of the cookie. + /// The cookie domain. + private static void CreateAuthTicket(this HttpContextBase http, + UserData userData, + int minutesPersisted, + string cookiePath, + string cookieName, + string cookieDomain) + { + var cookie = new HttpCookie(cookieName); + + if (GlobalSettings.UseSSL) + cookie.Secure = true; + + //ensure http only, this should only be able to be accessed via the server + cookie.HttpOnly = true; + cookie.Path = cookiePath; + cookie.Domain = cookieDomain; + cookie.Expires = DateTime.Now.AddMinutes(minutesPersisted); + + //serialize the user data + var json = JsonConvert.SerializeObject(userData); + //encrypt it + var encTicket = json.EncryptWithMachineKey(); + + //set the cookie value + cookie.Value = encTicket; + + http.Response.Cookies.Set(cookie); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs b/src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs new file mode 100644 index 0000000000..bd48b12116 --- /dev/null +++ b/src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs @@ -0,0 +1,110 @@ +using System; +using System.Web; +using System.Web.Security; +using Newtonsoft.Json; + +namespace Umbraco.Core.Security +{ + /// + /// A custom user identity for the Umbraco backoffice + /// + /// + /// All values are lazy loaded for performance reasons as the constructor is called for every single request + /// + internal class UmbracoBackOfficeIdentity : FormsIdentity + { + public UmbracoBackOfficeIdentity(FormsAuthenticationTicket ticket) + : base(ticket) + { + UserData = ticket.UserData; + EnsureDeserialized(); + } + + protected readonly string UserData; + internal UserData DeserializedData; + + public string UserContextId + { + get { return DeserializedData.UserContextId; } + } + + public int StartContentNode + { + get { return DeserializedData.StartContentNode; } + } + + public int StartMediaNode + { + get { return DeserializedData.StartMediaNode; } + } + + public string[] AllowedApplications + { + get { return DeserializedData.AllowedApplications; } + } + + public object Id + { + get { return DeserializedData.Id; } + } + + public string RealName + { + get { return DeserializedData.RealName; } + } + + public string Culture + { + get { return DeserializedData.Culture; } + } + + //public int SessionTimeout + //{ + // get + // { + // EnsureDeserialized(); + // return DeserializedData.SessionTimeout; + // } + //} + + public string[] Roles + { + get { return DeserializedData.Roles; } + } + + /// + /// This will ensure we only deserialize once + /// + /// + /// For performance reasons, we'll also check if there's an http context available, + /// if so, we'll chuck our instance in there so that we only deserialize once per request. + /// + protected void EnsureDeserialized() + { + if (DeserializedData != null) + return; + + if (HttpContext.Current != null) + { + //check if we've already done this in this request + var data = HttpContext.Current.Items[typeof(UmbracoBackOfficeIdentity)] as UserData; + if (data != null) + { + DeserializedData = data; + return; + } + } + + if (string.IsNullOrEmpty(UserData)) + { + throw new NullReferenceException("The " + typeof(UserData) + " found in the ticket cannot be empty"); + } + DeserializedData = JsonConvert.DeserializeObject(UserData); + + if (HttpContext.Current != null) + { + HttpContext.Current.Items[typeof (UmbracoBackOfficeIdentity)] = DeserializedData; + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Security/UserData.cs b/src/Umbraco.Core/Security/UserData.cs new file mode 100644 index 0000000000..feee9c9dfa --- /dev/null +++ b/src/Umbraco.Core/Security/UserData.cs @@ -0,0 +1,51 @@ +using System; +using System.Runtime.Serialization; + +namespace Umbraco.Core.Security +{ + /// + /// Data structure used to store information in the authentication cookie + /// + [DataContract(Name = "userData", Namespace = "")] + internal class UserData + { + public UserData() + { + AllowedApplications = new string[] {}; + Roles = new string[] {}; + } + + ///// + ///// When their session is going to expire (in ticks) + ///// + //[DataMember(Name = "timeout")] + //public long Timeout { get; set; } + + [DataMember(Name = "userContextId")] + public string UserContextId { get; set; } + + [DataMember(Name = "id")] + public object Id { get; set; } + + [DataMember(Name = "roles")] + public string[] Roles { get; set; } + + [DataMember(Name = "username")] + public string Username { get; set; } + + [DataMember(Name = "name")] + public string RealName { get; set; } + + [DataMember(Name = "startContent")] + public int StartContentNode { get; set; } + + [DataMember(Name = "startMedia")] + public int StartMediaNode { get; set; } + + [DataMember(Name = "allowedApps")] + public string[] AllowedApplications { get; set; } + + [DataMember(Name = "culture")] + public string Culture { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index b1b83ace68..f4011e90a8 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -666,6 +666,9 @@ + + + diff --git a/src/Umbraco.Core/UriExtensions.cs b/src/Umbraco.Core/UriExtensions.cs index e5de22456b..6ecb8d67e8 100644 --- a/src/Umbraco.Core/UriExtensions.cs +++ b/src/Umbraco.Core/UriExtensions.cs @@ -12,6 +12,7 @@ namespace Umbraco.Core /// public static class UriExtensions { + /// /// Checks if the current uri is a back office request /// @@ -19,11 +20,14 @@ namespace Umbraco.Core /// internal static bool IsBackOfficeRequest(this Uri url) { + var authority = url.GetLeftPart(UriPartial.Authority); var afterAuthority = url.GetLeftPart(UriPartial.Query) .TrimStart(authority) .TrimStart("/"); + + //check if this is in the umbraco back office return afterAuthority.InvariantStartsWith(GlobalSettings.Path.TrimStart("/")); } diff --git a/src/Umbraco.Web.UI/config/metablogConfig.config b/src/Umbraco.Web.UI/config/metablogConfig.config index 83cc2c1aa1..5621dbee75 100644 --- a/src/Umbraco.Web.UI/config/metablogConfig.config +++ b/src/Umbraco.Web.UI/config/metablogConfig.config @@ -5,7 +5,7 @@ 0 1080 False - Home + Base @@ -14,6 +14,6 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/controls/passwordChanger.ascx b/src/Umbraco.Web.UI/umbraco/controls/passwordChanger.ascx index fccd948dec..b9da0cbac7 100644 --- a/src/Umbraco.Web.UI/umbraco/controls/passwordChanger.ascx +++ b/src/Umbraco.Web.UI/umbraco/controls/passwordChanger.ascx @@ -1,16 +1,34 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="passwordChanger.ascx.cs" Inherits="umbraco.controls.passwordChanger" %> -Change password
+ - \ No newline at end of file +Change password
+ + diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/WebSecurity.cs index 08f5b0b67a..f45ff9c30e 100644 --- a/src/Umbraco.Web/Security/WebSecurity.cs +++ b/src/Umbraco.Web/Security/WebSecurity.cs @@ -5,12 +5,15 @@ using System.Web; using System.Web.Security; using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.Configuration; using Umbraco.Core.Logging; +using Umbraco.Core.Security; +using umbraco; using umbraco.BusinessLogic; using umbraco.DataLayer; using umbraco.businesslogic.Exceptions; using umbraco.cms.businesslogic.member; +using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings; +using UmbracoSettings = Umbraco.Core.Configuration.UmbracoSettings; namespace Umbraco.Web.Security { @@ -369,53 +372,51 @@ namespace Umbraco.Web.Security /// /// The umbraco user context ID. public string UmbracoUserContextId - { + { get { - if (StateHelper.Cookies.HasCookies && StateHelper.Cookies.UserContext.HasValue) + var authTicket = HttpContext.Current.GetUmbracoAuthTicket(); + if (authTicket == null) { - try - { - var encTicket = StateHelper.Cookies.UserContext.GetValue(); - if (string.IsNullOrEmpty(encTicket) == false) - { - return encTicket.DecryptWithMachineKey(); - } - } - catch (Exception ex) - { - if (ex is ArgumentException || ex is FormatException || ex is HttpException) - { - StateHelper.Cookies.UserContext.Clear(); - } - else - { - throw; - } - } + return ""; } - return ""; + var identity = authTicket.CreateUmbracoIdentity(); + if (identity == null) + { + HttpContext.Current.UmbracoLogout(); + return ""; + } + return identity.UserContextId; } set { - // zb-00004 #29956 : refactor cookies names & handling - if (StateHelper.Cookies.HasCookies) + if (value.IsNullOrWhiteSpace()) { - // Clearing all old cookies before setting a new one. - if (StateHelper.Cookies.UserContext.HasValue) - StateHelper.Cookies.ClearAll(); - - if (string.IsNullOrEmpty(value) == false) + HttpContext.Current.UmbracoLogout(); + } + else + { + var uid = GetUserId(value); + if (uid == -1) { - // Encrypt the value - var encTicket = value.EncryptWithMachineKey(); - - // Create new cookie. - StateHelper.Cookies.UserContext.SetValue(encTicket, 1); + HttpContext.Current.UmbracoLogout(); } else { - StateHelper.Cookies.UserContext.Clear(); + var user = User.GetUser(uid); + HttpContext.Current.CreateUmbracoAuthTicket( + new UserData + { + Id = uid, + AllowedApplications = user.Applications.Select(x => x.alias).ToArray(), + Culture = ui.Culture(user), + RealName = user.Name, + Roles = new string[] { user.UserType.Alias }, + StartContentNode = user.StartNodeId, + StartMediaNode = user.StartMediaId, + UserContextId = value, + Username = user.LoginName + }); } } } diff --git a/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs b/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs index 3979415dc7..be55343696 100644 --- a/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs +++ b/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs @@ -51,14 +51,6 @@ namespace Umbraco.Web.UI.Pages Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl), true); } } - - protected override void OnInit(EventArgs e) - { - base.OnInit(e); - - System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(ui.Culture(Security.CurrentUser)); - System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture; - } /// /// Gets/sets the app that this page is assigned to diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs index 604e61e55f..4ef5bc99a7 100644 --- a/src/Umbraco.Web/UmbracoModule.cs +++ b/src/Umbraco.Web/UmbracoModule.cs @@ -2,13 +2,17 @@ using System.Collections; using System.IO; using System.Linq; +using System.Threading; using System.Web; using System.Web.Routing; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Core.Security; using Umbraco.Web.Routing; using umbraco; +using umbraco.BasePages; using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings; using UmbracoSettings = Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Web.Configuration; @@ -29,7 +33,7 @@ namespace Umbraco.Web /// Begins to process a request. /// /// - void BeginRequest(HttpContextBase httpContext) + static void BeginRequest(HttpContextBase httpContext) { //we need to set the initial url in our ApplicationContext, this is so our keep alive service works and this must //exist on a global context because the keep alive service doesn't run in a web context. @@ -119,6 +123,58 @@ namespace Umbraco.Web RewriteToUmbracoHandler(httpContext, pcr); } + /// + /// Checks if the request is authenticated, if it is it sets the thread culture to the currently logged in user + /// + /// + /// + static void AuthenticateRequest(object sender, EventArgs e) + { + var app = (HttpApplication)sender; + var http = new HttpContextWrapper(app.Context); + + // do not process if client-side request + if (http.Request.Url.IsClientSideRequest()) + return; + + if (app.Request.Url.IsBackOfficeRequest() || app.Request.Url.IsInstallerRequest()) + { + var ticket = http.GetUmbracoAuthTicket(); + if (ticket != null) + { + //create the Umbraco user identity + var identity = ticket.CreateUmbracoIdentity(); + if (identity != null) + { + + //We'll leave setting custom identies/principals for 6.2, for now we'll just ensure that the cultures, etc.. are set + ////set the principal object + ////now we need to see if their session is still valid + //var timeout = BasePage.GetTimeout(identity.UserContextId); + //if (timeout > DateTime.Now.Ticks) + //{ + //var principal = new GenericPrincipal(identity, identity.Roles); + ////It is actually not good enough to set this on the current app Context and the thread, it also needs + //// to be set explicitly on the HttpContext.Current !! This is a strange web api thing that is actually + //// an underlying fault of asp.net not propogating the User correctly. + //if (HttpContext.Current != null) + //{ + // HttpContext.Current.User = principal; + //} + //app.Context.User = principal; + //Thread.CurrentPrincipal = principal; + //} + + //This is a back office/installer request, we will also set the culture/ui culture + Thread.CurrentThread.CurrentCulture = + Thread.CurrentThread.CurrentUICulture = + new System.Globalization.CultureInfo(identity.Culture); + + } + } + } + } + // returns a value indicating whether redirection took place and the request has // been completed - because we don't want to Response.End() here to terminate // everything properly. @@ -433,6 +489,8 @@ namespace Umbraco.Web BeginRequest(new HttpContextWrapper(httpContext)); }; + app.AuthenticateRequest += AuthenticateRequest; + app.PostResolveRequestCache += (sender, e) => { var httpContext = ((HttpApplication)sender).Context; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs index 55303bc219..1569a2d110 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs @@ -348,16 +348,12 @@ namespace umbraco.cms.presentation.user } } } - - #region Web Form Designer generated code - + protected override void OnInit(EventArgs e) { - // - // CODEGEN: This call is required by the ASP.NET Web Form Designer. - // - InitializeComponent(); - base.OnInit(e); + //lapps.SelectionMode = ListSelectionMode.Multiple; + lapps.RepeatLayout = RepeatLayout.Flow; + lapps.RepeatDirection = RepeatDirection.Vertical; } protected override void OnPreRender(EventArgs e) @@ -366,23 +362,9 @@ namespace umbraco.cms.presentation.user ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("../webservices/CMSNode.asmx")); // ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("../webservices/legacyAjaxCalls.asmx")); - - + } - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - //lapps.SelectionMode = ListSelectionMode.Multiple; - lapps.RepeatLayout = RepeatLayout.Flow; - lapps.RepeatDirection = RepeatDirection.Vertical; - } - - #endregion - /// /// Handles the Click event of the saveUser control. /// diff --git a/src/umbraco.businesslogic/BasePages/BasePage.cs b/src/umbraco.businesslogic/BasePages/BasePage.cs index 99c1172b1c..c2aec995ce 100644 --- a/src/umbraco.businesslogic/BasePages/BasePage.cs +++ b/src/umbraco.businesslogic/BasePages/BasePage.cs @@ -14,6 +14,7 @@ using Umbraco.Core.Services; using umbraco.BusinessLogic; using umbraco.DataLayer; using Umbraco.Core; +using Umbraco.Core.Security; namespace umbraco.BasePages { @@ -223,10 +224,10 @@ namespace umbraco.BasePages return false; } - private static long GetTimeout(string umbracoUserContextID) + internal static long GetTimeout(string umbracoUserContextId) { return ApplicationContext.Current.ApplicationCache.GetCacheItem( - CacheKeys.UserContextTimeoutCacheKey + umbracoUserContextID, + CacheKeys.UserContextTimeoutCacheKey + umbracoUserContextId, new TimeSpan(0, UmbracoTimeOutInMinutes / 10, 0), () => GetTimeout(true)); } @@ -257,50 +258,48 @@ namespace umbraco.BasePages { get { - if (StateHelper.Cookies.HasCookies && StateHelper.Cookies.UserContext.HasValue) + var authTicket = HttpContext.Current.GetUmbracoAuthTicket(); + if (authTicket == null) { - try - { - var encTicket = StateHelper.Cookies.UserContext.GetValue(); - if (string.IsNullOrEmpty(encTicket) == false) - { - return encTicket.DecryptWithMachineKey(); - } - } - catch (Exception ex) - { - if (ex is ArgumentException || ex is FormatException || ex is HttpException) - { - StateHelper.Cookies.UserContext.Clear(); - } - else - { - throw; - } - } + return ""; } - return ""; + var identity = authTicket.CreateUmbracoIdentity(); + if (identity == null) + { + HttpContext.Current.UmbracoLogout(); + return ""; + } + return identity.UserContextId; } set { - // zb-00004 #29956 : refactor cookies names & handling - if (StateHelper.Cookies.HasCookies) + if (value.IsNullOrWhiteSpace()) { - // Clearing all old cookies before setting a new one. - if (StateHelper.Cookies.UserContext.HasValue) - StateHelper.Cookies.ClearAll(); - - if (string.IsNullOrEmpty(value) == false) - { - // Encrypt the value - var encTicket = value.EncryptWithMachineKey(); - - // Create new cookie. - StateHelper.Cookies.UserContext.SetValue(encTicket, 1); + HttpContext.Current.UmbracoLogout(); + } + else + { + var uid = GetUserId(value); + if (uid == -1) + { + HttpContext.Current.UmbracoLogout(); } else { - StateHelper.Cookies.UserContext.Clear(); + var user = BusinessLogic.User.GetUser(uid); + HttpContext.Current.CreateUmbracoAuthTicket( + new UserData + { + Id = uid, + AllowedApplications = user.Applications.Select(x => x.alias).ToArray(), + Culture = ui.Culture(user), + RealName = user.Name, + Roles = new string[] {user.UserType.Alias}, + StartContentNode = user.StartNodeId, + StartMediaNode = user.StartMediaId, + UserContextId = value, + Username = user.LoginName + }); } } } diff --git a/src/umbraco.businesslogic/BasePages/UmbracoEnsuredPage.cs b/src/umbraco.businesslogic/BasePages/UmbracoEnsuredPage.cs index 870b1797b2..4fa4a3fea3 100644 --- a/src/umbraco.businesslogic/BasePages/UmbracoEnsuredPage.cs +++ b/src/umbraco.businesslogic/BasePages/UmbracoEnsuredPage.cs @@ -108,9 +108,6 @@ namespace umbraco.BasePages else Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl), true); } - - System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(ui.Culture(this.getUser())); - System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture; } } } \ No newline at end of file