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.
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.
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.
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
Hi,
'LogoutSuccess' is a static event handler on that class. You just need to attach an eventhandler like:
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));
} }
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));
}
Note: In the FHLBBackOfficeUserManager class, I am validating agaist active directory and not umbraco store.
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 :)
Yes, I checked and found through my own discovery that the events are hidden up through 7.4.x.
Thanks
is working on a reply...