Fixes: U4-2577 Can't save umbraco user - without re-filling in the password
Fixes: U4-541 Wrong dictionary key when using in backend template names This changes the way that the value that is stored in the auth cookie. Previously we just stored a GUID which was the user's contextid stored in the db, now we store encrypted values of a few necessary user objects. In 6.2 we'll actually set a real .Net user object on the HttpContext. For now, the http module will simply just ensure that the culture is set correctly for the currently logged in user.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the experimental canvas (live) editing on the frontend of the website
|
||||
/// </summary>
|
||||
|
||||
199
src/Umbraco.Core/Security/AuthenticationExtensions.cs
Normal file
199
src/Umbraco.Core/Security/AuthenticationExtensions.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extensions to create and renew and remove authentication tickets for the Umbraco back office
|
||||
/// </summary>
|
||||
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();
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// This clears the authentication cookie
|
||||
/// </summary>
|
||||
public static void UmbracoLogout(this HttpContextBase http)
|
||||
{
|
||||
Logout(http, UmbracoSettings.AuthCookieName);
|
||||
}
|
||||
|
||||
internal static void UmbracoLogout(this HttpContext http)
|
||||
{
|
||||
new HttpContextWrapper(http).UmbracoLogout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the umbraco authentication ticket
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <param name="userdata"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the umbraco auth ticket
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <returns></returns>
|
||||
public static FormsAuthenticationTicket GetUmbracoAuthTicket(this HttpContextBase http)
|
||||
{
|
||||
return GetAuthTicket(http, UmbracoSettings.AuthCookieName);
|
||||
}
|
||||
|
||||
internal static FormsAuthenticationTicket GetUmbracoAuthTicket(this HttpContext http)
|
||||
{
|
||||
return new HttpContextWrapper(http).GetUmbracoAuthTicket();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This clears the authentication cookie
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <param name="cookieName"></param>
|
||||
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) });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In v6 this is a custom cookie, in v7 this is a real formsauth cookie.
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <param name="cookieName"></param>
|
||||
/// <returns></returns>
|
||||
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<UserData>(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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a custom umbraco auth cookie with the data specified
|
||||
/// </summary>
|
||||
/// <param name="http">The HTTP.</param>
|
||||
/// <param name="userData">The user data.</param>
|
||||
/// <param name="minutesPersisted">The minutes persisted.</param>
|
||||
/// <param name="cookiePath">The cookie path.</param>
|
||||
/// <param name="cookieName">Name of the cookie.</param>
|
||||
/// <param name="cookieDomain">The cookie domain.</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
110
src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs
Normal file
110
src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.Security;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom user identity for the Umbraco backoffice
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All values are lazy loaded for performance reasons as the constructor is called for every single request
|
||||
/// </remarks>
|
||||
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; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This will ensure we only deserialize once
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// </remarks>
|
||||
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>(UserData);
|
||||
|
||||
if (HttpContext.Current != null)
|
||||
{
|
||||
HttpContext.Current.Items[typeof (UmbracoBackOfficeIdentity)] = DeserializedData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
src/Umbraco.Core/Security/UserData.cs
Normal file
51
src/Umbraco.Core/Security/UserData.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// Data structure used to store information in the authentication cookie
|
||||
/// </summary>
|
||||
[DataContract(Name = "userData", Namespace = "")]
|
||||
internal class UserData
|
||||
{
|
||||
public UserData()
|
||||
{
|
||||
AllowedApplications = new string[] {};
|
||||
Roles = new string[] {};
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// When their session is going to expire (in ticks)
|
||||
///// </summary>
|
||||
//[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; }
|
||||
}
|
||||
}
|
||||
@@ -666,6 +666,9 @@
|
||||
<Compile Include="Publishing\PublishStatus.cs" />
|
||||
<Compile Include="Publishing\PublishStatusType.cs" />
|
||||
<Compile Include="RenderingEngine.cs" />
|
||||
<Compile Include="Security\AuthenticationExtensions.cs" />
|
||||
<Compile Include="Security\UmbracoBackOfficeIdentity.cs" />
|
||||
<Compile Include="Security\UserData.cs" />
|
||||
<Compile Include="Serialization\AbstractSerializationService.cs" />
|
||||
<Compile Include="Serialization\Formatter.cs" />
|
||||
<Compile Include="Serialization\IFormatter.cs" />
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class UriExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current uri is a back office request
|
||||
/// </summary>
|
||||
@@ -19,11 +20,14 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
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("/"));
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<user>0</user>
|
||||
<startNode>1080</startNode>
|
||||
<fullTree>False</fullTree>
|
||||
<documentTypeAlias>Home</documentTypeAlias>
|
||||
<documentTypeAlias>Base</documentTypeAlias>
|
||||
<fields>
|
||||
<categories>
|
||||
</categories>
|
||||
@@ -14,6 +14,6 @@
|
||||
<excerpt>
|
||||
</excerpt>
|
||||
</fields>
|
||||
<mediaObjectSupport enabled="True" folderId="-1" mediaTypeAlias="image" mediaTypeFileProperty="umbracoFile" />
|
||||
<mediaObjectSupport enabled="True" folderId="-1" mediaTypeAlias="Image" mediaTypeFileProperty="umbracoFile" />
|
||||
</channel>
|
||||
</metablogapi>
|
||||
@@ -1,16 +1,34 @@
|
||||
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="passwordChanger.ascx.cs" Inherits="umbraco.controls.passwordChanger" %>
|
||||
|
||||
<a href="#" onclick="if (document.getElementById('umbPasswordChanger').style.display == '' || document.getElementById('umbPasswordChanger').style.display == 'none') {document.getElementById('umbPasswordChanger').style.display = 'block'; this.style.display = 'none';}">Change password</a><br />
|
||||
<script type="text/javascript">
|
||||
(function ($) {
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
Umbraco.Controls.PasswordChanger = {
|
||||
toggle: function (e) {
|
||||
if (!$("#umbPasswordChanger").is(":visible")) {
|
||||
ValidatorEnable(document.getElementById('<%=CompareValidator1.ClientID %>'), true);
|
||||
$(e).closest(".propertyItem").replaceWith($("#umbPasswordChanger"));
|
||||
$("#umbPasswordChanger").show();
|
||||
$(e).hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
</script>
|
||||
|
||||
<div id="umbPasswordChanger" style="display: none;">
|
||||
<table>
|
||||
<tr><th style="width: 270px;"><%=umbraco.ui.GetText("user", "newPassword")%>:</th><td style="width: 359px">
|
||||
<asp:TextBox ID="umbPasswordChanger_passwordNew" autocomplete="off" AutoCompleteType="None" TextMode="password" runat="server"></asp:TextBox>
|
||||
</td></tr>
|
||||
<tr><th><%=umbraco.ui.GetText("user", "confirmNewPassword")%>:</th><td style="width: 359px">
|
||||
<asp:TextBox ID="umbPasswordChanger_passwordNewConfirm" autocomplete="off" AutoCompleteType="None" TextMode="password" runat="server"></asp:TextBox>
|
||||
<asp:CompareValidator ID="CompareValidator1" runat="server" ErrorMessage="Passwords must match" ControlToValidate="umbPasswordChanger_passwordNew"
|
||||
ControlToCompare="umbPasswordChanger_passwordNewConfirm" Operator="Equal"></asp:CompareValidator>
|
||||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<a href="#" onclick="Umbraco.Controls.PasswordChanger.toggle(this);">Change password</a><br />
|
||||
|
||||
<div class="propertyItem" id="umbPasswordChanger" style="display: none;">
|
||||
|
||||
<div class="propertyItemheader"><%=umbraco.ui.GetText("user", "newPassword")%></div>
|
||||
<div class="propertyItemContent">
|
||||
<asp:TextBox ID="umbPasswordChanger_passwordNew" autocomplete="off" AutoCompleteType="None" TextMode="password" runat="server"></asp:TextBox>
|
||||
</div>
|
||||
|
||||
<div class="propertyItemheader"><%=umbraco.ui.GetText("user", "confirmNewPassword")%></div>
|
||||
<div class="propertyItemContent">
|
||||
<asp:TextBox ID="umbPasswordChanger_passwordNewConfirm" autocomplete="off" AutoCompleteType="None" TextMode="password" runat="server"></asp:TextBox>
|
||||
<asp:CompareValidator ID="CompareValidator1" runat="server" Enabled="False" ErrorMessage="Passwords must match" ControlToValidate="umbPasswordChanger_passwordNew"
|
||||
ControlToCompare="umbPasswordChanger_passwordNewConfirm" Operator="Equal"></asp:CompareValidator>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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
|
||||
/// </summary>
|
||||
/// <value>The umbraco user context ID.</value>
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the app that this page is assigned to
|
||||
|
||||
@@ -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.
|
||||
/// </summary>
|
||||
/// <param name="httpContext"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the request is authenticated, if it is it sets the thread culture to the currently logged in user
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
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;
|
||||
|
||||
@@ -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"));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
//lapps.SelectionMode = ListSelectionMode.Multiple;
|
||||
lapps.RepeatLayout = RepeatLayout.Flow;
|
||||
lapps.RepeatDirection = RepeatDirection.Vertical;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Click event of the saveUser control.
|
||||
/// </summary>
|
||||
|
||||
@@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user