diff --git a/src/Umbraco.Core/Security/BackOfficeUserManager.cs b/src/Umbraco.Core/Security/BackOfficeUserManager.cs index f86c06c39c..cf6e9a737b 100644 --- a/src/Umbraco.Core/Security/BackOfficeUserManager.cs +++ b/src/Umbraco.Core/Security/BackOfficeUserManager.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Text; +using System.Threading.Tasks; using System.Web.Security; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; @@ -9,8 +10,6 @@ using Umbraco.Core.Services; namespace Umbraco.Core.Security { - - /// /// Default back office user manager /// @@ -21,6 +20,18 @@ namespace Umbraco.Core.Security { } + public BackOfficeUserManager( + IUserStore store, + IdentityFactoryOptions options, + MembershipProviderBase membershipProvider) + : base(store) + { + if (options == null) throw new ArgumentNullException("options"); + var manager = new BackOfficeUserManager(store); + InitUserManager(manager, membershipProvider, options); + } + + #region Static Create methods /// /// Creates a BackOfficeUserManager instance with all default options and the default BackOfficeUserManager /// @@ -40,8 +51,8 @@ namespace Umbraco.Core.Security if (externalLoginService == null) throw new ArgumentNullException("externalLoginService"); var manager = new BackOfficeUserManager(new BackOfficeUserStore(userService, externalLoginService, membershipProvider)); - - return InitUserManager(manager, membershipProvider, options); + manager.InitUserManager(manager, membershipProvider, options); + return manager; } /// @@ -56,13 +67,10 @@ namespace Umbraco.Core.Security BackOfficeUserStore customUserStore, MembershipProviderBase membershipProvider) { - if (options == null) throw new ArgumentNullException("options"); - if (customUserStore == null) throw new ArgumentNullException("customUserStore"); - - var manager = new BackOfficeUserManager(customUserStore); - - return InitUserManager(manager, membershipProvider, options); - } + var manager = new BackOfficeUserManager(customUserStore, options, membershipProvider); + return manager; + } + #endregion /// /// Initializes the user manager with the correct options @@ -71,7 +79,7 @@ namespace Umbraco.Core.Security /// /// /// - private static BackOfficeUserManager InitUserManager(BackOfficeUserManager manager, MembershipProviderBase membershipProvider, IdentityFactoryOptions options) + protected void InitUserManager(BackOfficeUserManager manager, MembershipProviderBase membershipProvider, IdentityFactoryOptions options) { // Configure validation logic for usernames manager.UserValidator = new UserValidator(manager) @@ -125,10 +133,10 @@ namespace Umbraco.Core.Security //}); //manager.EmailService = new EmailService(); - //manager.SmsService = new SmsService(); - - return manager; + //manager.SmsService = new SmsService(); } + + } /// @@ -171,5 +179,39 @@ namespace Umbraco.Core.Security } #endregion + /// + /// Logic used to validate a username and password + /// + /// + /// + /// + /// + /// By default this uses the standard ASP.Net Identity approach which is: + /// * Get password store + /// * Call VerifyPasswordAsync with the password store + user + password + /// * Uses the PasswordHasher.VerifyHashedPassword to compare the stored password + /// + /// In some cases people want simple custom control over the username/password check, for simplicity + /// sake, developers would like the users to simply validate against an LDAP directory but the user + /// data remains stored inside of Umbraco. + /// See: http://issues.umbraco.org/issue/U4-7032 for the use cases. + /// + /// We've allowed this check to be overridden with a simple callback so that developers don't actually + /// have to implement/override this class. + /// + public async override Task CheckPasswordAsync(T user, string password) + { + if (BackOfficeUserPasswordChecker == null) + { + //use the default behavior + return await base.CheckPasswordAsync(user, password); + } + return await BackOfficeUserPasswordChecker.CheckPasswordAsync(user, password); + } + + /// + /// Gets/sets the default back office user password checker + /// + public IBackOfficeUserPasswordChecker BackOfficeUserPasswordChecker { get; set; } } } diff --git a/src/Umbraco.Core/Security/IBackOfficeUserPasswordChecker.cs b/src/Umbraco.Core/Security/IBackOfficeUserPasswordChecker.cs new file mode 100644 index 0000000000..bd9abcdee2 --- /dev/null +++ b/src/Umbraco.Core/Security/IBackOfficeUserPasswordChecker.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; +using Umbraco.Core.Models.Identity; + +namespace Umbraco.Core.Security +{ + /// + /// Used by the BackOfficeUserManager to check the username/password which allows for developers to more easily + /// set the logic for this procedure. + /// + public interface IBackOfficeUserPasswordChecker + { + Task CheckPasswordAsync(BackOfficeIdentityUser user, string password); + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 4552cac7f5..54c7c44ff5 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -463,6 +463,7 @@ +