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
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));
});
I would use a middleware, in which I would check the HttpContext for the current principal and check the IsChangePassword property value of the underlying user.
Then, according to the IsChangePassword property value, I would redirect the current request to the change password form.
The pro of this solution is that you don't need to edit any actions and controllers.
The con is that you add a if statement to every requests but additional configuration is possible.