1

I am trying to implement following logic:

Whenever a new user is created, a default hardcoded password would be assigned. If the new created user logged in, the system would FORCE the user to change their default password

I have successfully achieved the logic above with this code in my controllers:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //Check if authenticated
        if (filterContext.HttpContext.User.Identity.IsAuthenticated && !filterContext.HttpContext.Request.RawUrl.Equals("/Account/ChangePassword") && !filterContext.HttpContext.Request.RawUrl.Equals("/Account/LogOff"))
        {
            //Get user Data
            MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
            if (currentUser.GetPassword().Equals("password"))
            {
                filterContext.Result = new RedirectToRouteResult(
                                       new RouteValueDictionary 
                                        { 
                                            { "controller", "Account" }, 
                                            { "action", "ChangePassword" } 
                                        });
            }
        }
    }

However, now i have to copy paste this code to all of my controllers. Does this disrespect the DRY principle in mvc3 ?

If Yes, Where or how should i place this code so it can be globally implemented to all of my controllers? I tried to paste it in Global.asax but i got an error that said "No Suitable Method Found to Override"

Ressa_Panda
  • 35
  • 10
  • 2
    Create a base controller that inherits Controller and have this method defined there. Then have all your other controllers inherit the base controller class you created. – maccettura Oct 14 '17 at 03:15
  • Thank you very much...!!! i didn't know it's this simple.... :D – Ressa_Panda Oct 14 '17 at 03:27
  • 1
    This also could be achieved using a global ActionFilter – Fran Oct 14 '17 at 03:34
  • Where do i put my actionfilter class? is it in controller? – Ressa_Panda Oct 14 '17 at 03:47
  • Yikes! You're using cleartext or reversible passwords? I hope you have a good excuse to give when your site is hacked and you leak all those passwords onto the internet. – Erik Funkenbusch Oct 14 '17 at 04:15
  • Erik has a good point. Hard coding a password isn't a very good solution. Creating a random password would be a better solution (although there are probably solutions that are better still). It would also be better if you compare hashes of passwords rather than actual clear text. – NightOwl888 Oct 14 '17 at 05:31
  • Thank you for the warning, i will implement more secure solutions...!!! =D – Ressa_Panda Oct 16 '17 at 01:42

2 Answers2

3

As previously described by others in the comment section, you could do this using base controller or using action filter.

For now, you may consider using actionfilter creating like this.

public class YourActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {

    }
}


     [YourActionFilter]
     public class HomeController : Controller
     {
          public ActionResult Index()
          {
               return View();
          }

          public ActionResult About()
          {
               return View();
          }
     }

More details you can find in MS doc

RJ-
  • 136
  • 1
  • 13
0

Use a global filter. Here is an example of an action filter.

public class ForceLoginActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //Check if authenticated
        if (filterContext.HttpContext.User.Identity.IsAuthenticated && !filterContext.HttpContext.Request.RawUrl.Equals("/Account/ChangePassword") && !filterContext.HttpContext.Request.RawUrl.Equals("/Account/LogOff"))
        {
            //Get user Data
            MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
            if (currentUser.GetPassword().Equals("password"))
            {
                filterContext.Result = new RedirectToRouteResult(
                                       new RouteValueDictionary
                                        {
                                        { "controller", "Account" },
                                        { "action", "ChangePassword" }
                                        });
            }
        }
    }
}

Usage

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new ForceLoginActionFilter());
    }
}

Reference: Filtering in ASP.NET MVC

NOTE: Never use a base controller in ASP.NET MVC. This will almost always lead to creating a god object that is difficult to maintain.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212