I am using ASP.net core 2.0. I added a flag column called IsChangePassword to my AspNetUsers table and to my ApplicationUser class. The idea is to force the user to change their password. There is always a chance that they might enter a url to bypass being forced to change their password. I want to have it check that property every time a webpage is being loaded and redirect to ChangePassword if that flag is true.
You need a resource filter, which you'll need to inject with both UserManager<TUser>
and IUrlHelperFactory
. The former will obviously be used to check the value of IsChangePassword
, while the latter will be necessary to check the current URL against your chosen redirect URL, to prevent an endless redirect loop. Simply:
public class ChangePasswordResourceFilter : IAsyncResourceFilter
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IUrlHelperFactory _urlHelperFactory;
public ChangePasswordResourceFilter(UserManager<ApplicationUser> userManager, IUrlHelperFactory urlHelperFactory)
{
_userManager = userManager;
_urlHelperFactory = urlHelperFactory;
}
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
var urlHelper = _urlHelperFactory.GetUrlHelper(context);
var redirectUrl = urlHelper.Page("~/PasswordChange");
var currentUrl = context.HttpContext.Request.Path;
if (redirectUrl != currentUrl)
{
var user = await _userManager.GetUserAsync(context.HttpContext.User);
if (user?.IsChangePassword ?? false)
{
context.Result = new RedirectResult(redirectUrl);
}
}
await next();
}
}
Then, in Startup.ConfigureServices
:
services.AddScoped<ChangePasswordResourceFilter>();
...
services.AddMvc(o =>
{
o.Filters.Add(typeof(ChangePasswordResourceFilter));
});