Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Tom 161 posts 322 karma points
    Sep 28, 2018 @ 10:19
    Tom
    0

    Logout Event Handler Example

    Hello: We are on Umbraco 7.5.9 and want to run some custom code when user logout of the backend of Umbraco. I have searched google for an answer and found one link (see below) that was somewhat helpful but when I tried adding this to our custom backOfficeManager class, IdentityAuditEventArgs is not accessible and the code does not compile. I looked at documentation and the class is public but I can't get to it.

        protected virtual void OnLogoutSuccess(IdentityAuditEventArgs e)
        {
            if (LogoutSuccess != null) LogoutSuccess(this, e);
        }
    

    https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Core/Security/BackOfficeUserManager.cs#L721

    Basically, all I wish to do is "intercept the logout button event handler" with my custom code?

    Does anyone have an example of how t do this?

    Thanks

    Tom

  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Sep 28, 2018 @ 10:35
    Søren Gregersen
    1

    Hi,

    'LogoutSuccess' is a static event handler on that class. You just need to attach an eventhandler like:

    public class UmbracoEvents : IApplicationEventHandler 
    {
        public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            BackOfficeUserManager.LogoutSuccess += (sender, args) => {
                // your code
            };
       }
    }
    
  • Tom 161 posts 322 karma points
    Sep 28, 2018 @ 10:49
    Tom
    0

    Thank you so much for helping.

    But this did not work for me. In my ApplicationEvents.cs (which looks just like yours) and in the method OnApplicationStarted().... when I type in BackOfficeUserManager. The only options I have are these Create Equals OwinMarketKey ReferenceEquals. I see no option for LogoutSuccess.

    What am I missing? Can you help further.

    ApplicationEvents.cs

    using System.Web; using System.Web.Mvc; using System.Web.Routing; using log4net; using Umbraco.Core; using System.Web.Optimization; using Mantle.core.ContentFinders; using Umbraco.Web.Routing; using Umbraco.Core.Security;

    namespace Mantle.core { public class ApplicationEvents : IApplicationEventHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(ApplicationEvents));

        public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication,
            ApplicationContext applicationContext)
        {
            umbracoApplication.Error += umbracoApplication_Error;
        }
    
        void umbracoApplication_Error(object sender, System.EventArgs e)
        {
            var error = HttpContext.Current.Server.GetLastError();
            Log.Error(error);
        }
    
        public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication,ApplicationContext applicationContext)
        {
            //NOTE:  This will "precache" the members for the search function
            var mu = new MemberUtilities();
            // ReSharper disable once UnusedVariable
            var members = mu.GetMembers();
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            var b = ContentFinderResolver.Current.Finders;
        }
    
        public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            ContentLastChanceFinderResolver.Current.SetFinder(new PageNotFoundContentFinder());
       }
    

    } }

    FHLBBackOfficeUserManager.cs

    using System; using System.Collections.Generic; using System.Configuration; using System.DirectoryServices.AccountManagement; using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Umbraco.Core.Models.Identity; using Umbraco.Core.Security; using Umbraco.Core; using Umbraco.Core.Services;

    namespace Mantle.core.Security { public class FhlbBackOfficeUserManager : BackOfficeUserManager { private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(FhlbBackOfficeUserManager));

        public FhlbBackOfficeUserManager(IUserStore<BackOfficeIdentityUser, int> store) : base(store)
        {
        }
    
        public static FhlbBackOfficeUserManager InitUserManager(FhlbBackOfficeUserManager manager,
            MembershipProviderBase membershipProvider, IdentityFactoryOptions<BackOfficeUserManager> options)
        {
            var dataProtectionProvider = options.DataProtectionProvider;
            if (dataProtectionProvider != null)
            {
                manager.UserTokenProvider = new DataProtectorTokenProvider<BackOfficeIdentityUser, int>(dataProtectionProvider.Create("ASP.NET Identity"));
            }
    
            // could specific other provider options here
    
            //custom identity factory for creating the identity object for which we auth against in the back office
            manager.ClaimsIdentityFactory = new BackOfficeClaimsIdentityFactory();
    
            return manager;
        }
    
        public override Task<IdentityResult> ChangePasswordAsync(int userId, string currentPassword, string newPassword)
        {
            UserService usrSvc = (UserService)ApplicationContext.Current.Services.UserService;
    
            var user = usrSvc.GetById(userId);
    
            using (var context = new PrincipalContext(ContextType.Domain, ConfigSettings.ADDomain))
            {
                using (var up = UserPrincipal.FindByIdentity(context, user.Username))
                {
                    try
                    {
                        up.ChangePassword(currentPassword, newPassword);
                    }
                    catch (Exception ex)
                    {
                        return Task.FromResult(IdentityResult.Failed());
                    }
                }
            }
            return Task.FromResult(IdentityResult.Success); // base.ChangePasswordAsync(userId, currentPassword, newPassword);
        }
        public override Task<BackOfficeIdentityUser> FindByNameAsync(string userName)
        {
            // Calls this method to check if account exists
            using (var context = new PrincipalContext(ContextType.Domain, ConfigSettings.ADDomain))
            {
                using (var user = UserPrincipal.FindByIdentity(context, userName))
                {
                    if (user != null)
                    {
                        SecurityUtil.CreateUserIfNecessary(userName, "", user.EmailAddress);
                    }
                }
            }
            return base.FindByNameAsync(userName);
        }
        public override Task<bool> CheckPasswordAsync(BackOfficeIdentityUser user, string password)
        {
            if (ValidateUser(user.UserName, password))
            {
                return Task.FromResult(true);
            }
            return Task.FromResult(false);
        }
    
        public override Task<IList<string>> GetRolesAsync(int userId)
        {
            UserService usrSvc = (UserService)ApplicationContext.Current.Services.UserService;
    
            var user = usrSvc.GetById(userId);
    
            Log.InfoFormat("Verifying claims for {0}", user.Name);
    
            SecurityUtil.VerifyAccessForUser(user);
    
            var val = base.GetRolesAsync(userId);
            return val;
        }
        public bool ValidateUser(string username, string password)
        {
            bool isValid = false;
    
            Log.DebugFormat(@"Validating user {0}", username);
            try
            {
                using (var context = new PrincipalContext(ContextType.Domain, ConfigSettings.ADDomain))
                {
                    if (context.ValidateCredentials(username, password))
                    {
                        Log.DebugFormat(@"Password is valid for {0}", username);
    
                        UserPrincipal user = UserPrincipal.FindByIdentity(context, username);
    
                        if (user == null)
                            throw new Exception(@"Could not retrieve user information from Active Directory");
    
                        isValid = true;
                        MembersOnlySecurityUtil.CreateBackendFHLBPWSCookie(username);
                    }
                    else
                    {
                        Log.DebugFormat(@"Could not verify password for account {0}", username);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.FatalFormat(@"Unable to authenticate to AD: {0}", ex.Message);
            }
    
            return isValid;
        }
    }
    

    }

    Note: In the FHLBBackOfficeUserManager class, I am validating agaist active directory and not umbraco store.

  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Sep 28, 2018 @ 13:35
    Søren Gregersen
    100

    Sorry, I didn't check the versions. The events where added after 7.5.x

    I would suggest you look at how it is implemented in umbraco, and copy that :)

  • Tom 161 posts 322 karma points
    Sep 28, 2018 @ 14:51
    Tom
    0

    Yes, I checked and found through my own discovery that the events are hidden up through 7.4.x.

    Thanks

Please Sign in or register to post replies

Write your reply to:

Draft