diff --git a/src/Umbraco.Core/Security/AuthenticationExtensions.cs b/src/Umbraco.Core/Security/AuthenticationExtensions.cs index f5b41d0e34..7c4d2980b1 100644 --- a/src/Umbraco.Core/Security/AuthenticationExtensions.cs +++ b/src/Umbraco.Core/Security/AuthenticationExtensions.cs @@ -76,7 +76,7 @@ namespace Umbraco.Core.Security /// This will return the current back office identity. /// /// - /// + /// /// If set to true and a back office identity is not found and not authenticated, this will attempt to authenticate the /// request just as is done in the Umbraco module and then set the current identity if it is valid /// @@ -89,12 +89,20 @@ namespace Umbraco.Core.Security if (http.User == null) return null; //there's no user at all so no identity var identity = http.User.Identity as UmbracoBackOfficeIdentity; if (identity != null) return identity; + if (authenticateRequestIfNotFound == false) return null; + //even if authenticateRequestIfNotFound is true we cannot continue if the request is actually authenticated // which would mean something strange is going on that it is not an umbraco identity. if (http.User.Identity.IsAuthenticated) return null; + + //So the user is not authed but we've been asked to do the auth if authenticateRequestIfNotFound = true, + // which might occur in old webforms style things or for routes that aren't included as a back office request. + // in this case, we are just reverting to authing using the cookie. + + // TODO: Even though this is in theory legacy, we have legacy bits laying around and we'd need to do the auth based on + // how the Module will eventually do it (by calling in to any registered authenticators). - //now we just need to try to authenticate the current request var ticket = http.GetUmbracoAuthTicket(); if (http.AuthenticateCurrentRequest(ticket, true)) { diff --git a/src/Umbraco.Web/Install/Controllers/InstallController.cs b/src/Umbraco.Web/Install/Controllers/InstallController.cs index 02fc2b3511..3d6f397f9f 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallController.cs @@ -57,8 +57,7 @@ namespace Umbraco.Web.Install.Controllers switch (result) { case ValidateRequestAttempt.FailedNoPrivileges: - case ValidateRequestAttempt.FailedTimedOut: - case ValidateRequestAttempt.FailedNoContextId: + case ValidateRequestAttempt.FailedNoContextId: return Redirect(SystemDirectories.Umbraco + "/AuthorizeUpgrade?redir=" + Server.UrlEncode(Request.RawUrl)); } } diff --git a/src/Umbraco.Web/Security/ValidateRequestAttempt.cs b/src/Umbraco.Web/Security/ValidateRequestAttempt.cs index 1ec1dca2f0..62fd68a2ef 100644 --- a/src/Umbraco.Web/Security/ValidateRequestAttempt.cs +++ b/src/Umbraco.Web/Security/ValidateRequestAttempt.cs @@ -4,7 +4,9 @@ { Success, FailedNoPrivileges, - FailedTimedOut, + + //FailedTimedOut, + FailedNoContextId, FailedNoSsl } diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/WebSecurity.cs index fbf30a002e..e8064b05ca 100644 --- a/src/Umbraco.Web/Security/WebSecurity.cs +++ b/src/Umbraco.Web/Security/WebSecurity.cs @@ -322,38 +322,37 @@ namespace Umbraco.Web.Security public bool ValidateCurrentUser() { var result = ValidateCurrentUser(false); - return result == ValidateRequestAttempt.Success; + return result == ValidateRequestAttempt.Success; } /// - /// Validates the current user + /// Validates the current user assigned to the request and ensures the stored user data is valid /// /// set to true if you want exceptions to be thrown if failed /// internal ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions) { - var ticket = _httpContext.GetUmbracoAuthTicket(); + //This will first check if the current user is already authenticated - which should be the case in nearly all circumstances + // since the authentication happens in the Module, that authentication also checks the ticket expiry. We don't + // need to check it a second time because that requires another decryption phase and nothing can tamper with it during the request. - if (ticket != null) + if (_httpContext.User.Identity.IsAuthenticated == false) { - if (ticket.Expired == false) - { - var user = CurrentUser; - - // Check for console access - if (user.IsApproved == false || (user.IsLockedOut && GlobalSettings.RequestIsInUmbracoApplication(_httpContext))) - { - if (throwExceptions) throw new ArgumentException("You have no priviledges to the umbraco console. Please contact your administrator"); - return ValidateRequestAttempt.FailedNoPrivileges; - } - return ValidateRequestAttempt.Success; - } - if (throwExceptions) throw new ArgumentException("User has timed out!!"); - return ValidateRequestAttempt.FailedTimedOut; + //There is no user + if (throwExceptions) throw new InvalidOperationException("The user has no umbraco contextid - try logging in"); + return ValidateRequestAttempt.FailedNoContextId; } - if (throwExceptions) throw new InvalidOperationException("The user has no umbraco contextid - try logging in"); - return ValidateRequestAttempt.FailedNoContextId; + var user = CurrentUser; + + // Check for console access + if (user == null || user.IsApproved == false || (user.IsLockedOut && GlobalSettings.RequestIsInUmbracoApplication(_httpContext))) + { + if (throwExceptions) throw new ArgumentException("You have no priviledges to the umbraco console. Please contact your administrator"); + return ValidateRequestAttempt.FailedNoPrivileges; + } + return ValidateRequestAttempt.Success; + } /// diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs index 8a1016cacc..6a44f214ef 100644 --- a/src/Umbraco.Web/UmbracoModule.cs +++ b/src/Umbraco.Web/UmbracoModule.cs @@ -167,7 +167,7 @@ namespace Umbraco.Web /// context and thread principle object /// /// - /// + /// /// /// We will set the identity, culture, etc... for any request that is: /// * A back office request @@ -187,6 +187,11 @@ namespace Umbraco.Web if (ShouldAuthenticateRequest(req, UmbracoContext.Current.OriginalRequestUrl)) { + //TODO: Here we should have an authentication mechanism, this mechanism should be smart in the way that the ASP.Net 5 pipeline works + // in which each registered handler will attempt to authenticate and if it fails it will just call Next() so the next handler + // executes. If it is successful, it doesn't call next and assigns the current user/principal. + // This might actually all be possible with ASP.Net Identity and how it is setup to work already, need to investigate. + var ticket = http.GetUmbracoAuthTicket(); http.AuthenticateCurrentRequest(ticket, ShouldIgnoreTicketRenew(UmbracoContext.Current.OriginalRequestUrl, http) == false);