1

I wanted to add a simple login. So I thought the best way would be to add the credentials in a database and then query that and if the username and password mathches you get logged in. This is working, well it querys the db and you get logged in and redirected to home. Then I tried accessing home through the url and noticed that I can do that without login. So then I figured that I should use the

[Authorize]

attribute on the Home Controller as I don't want unauthorized users to access it so the should be redirected back to the login page. This does not work. when I use authorize on the controller I get a error in the application.

Object reference not set to an instance of an object.

In the web.config it looks like this:

<authentication mode="Forms">
  <forms loginUrl="~/Login/Index" timeout="2880" /> <-- I have changed the login url to my login controller.
</authentication>

And my login controller like this.

public ActionResult Index(UserModel model) <-- I query the db in the model.
    {
        if (!ModelState.IsValid)
        {
            return View(model);

        }

        if(!model.IsAdmin(model.UserName, model.Password))
        {  
            ModelState.AddModelError("username", "you are not a admin");
            return View(model);
        }
        FormsAuthentication.SetAuthCookie(model.UserName, false);

        return RedirectToAction("Index", "Home");

        }

So how is the proper way to use this Authorize attribute? Can I even use it the way I'm using it? Am I missing something in the web.config? Regards!

Some update to this. As it was not working I added this to the web.config:

 <authentication mode="Forms">
        <forms loginUrl="~/Account/LogOn" timeout="5">
        </forms>
    </authentication>
    <membership defaultProvider="MyMembershipProvider">
        <providers>
            <clear/>
            <add name="MyMembershipProvider" type="MyNamespace.MyMembershipProvider"
                 enablePasswordRetrieval="false" 
                 enablePasswordReset="true"
                 requiresQuestionAndAnswer="false"
                 userIsOnlineTimeWindow="2" 
                 requiresUniqueEmail="false"
                 passwordFormat="Hashed"
                 maxInvalidPasswordAttempts="5" 
                 minRequiredPasswordLength="6" 
                 minRequiredNonalphanumericCharacters="0" 
                 passwordAttemptWindow="10"
                 applicationName="/" />
        </providers>
    </membership>

And a membershipprovider with hardcoded credentials:

public class MyMembershipProvider : MembershipProvider 
{
    public override bool ValidateUser(string username, string password)
    {
        if (username.Equals("user", StringComparison.CurrentCultureIgnoreCase) && password.Equals("myPassword"))
            return true;
        else
            return false;
    }

Then I tried decorating my HomeController with the Authorization attribute like this:

 [Authorize()]
public class HomeController : Controller
{}

But still getting the same error. I mean I can login but when I reach "Home" I get the same error as before. What in earths name is this?! Any clues to this?!

Regards!

Tim
  • 531
  • 2
  • 7
  • 25

2 Answers2

0

The problem is this:

return RedirectToAction("Index", "Home");

You are redirecting to the Index action of your Home controller which expects you to pass in a model of some type(not sure because you haven't posted the Home controller Index action). When you call the RedirectToAction without the model specified, it will cause an error when you try to access any elements of that model because the model is going to be null. That is why you get the

Object reference not set to an instance of an object.

This happens a lot when you call a view with an null model. You need to change your redirect to include the model that the controller expects:

 return RedirectToAction("Index", "Home", SomeModel)

I think you are trying to use the [Authorize] correctly. It just needs to be above the Controller Action that you are trying to lock down. You should post the Index action of the Home controller to get some more specific answers on your problem.

Rondel
  • 4,811
  • 11
  • 41
  • 67
  • ok, but can I not decorate the whole class with the [Authorize] attribute instead of just the action?! Thanks – Tim Aug 17 '11 at 08:39
  • Yeah you can add the [Authorize] attribute at the controller level instead of for specific actions. Just move the [Authorize] keyword directly above the Controller class declaration. – Rondel Aug 17 '11 at 14:41
0

Did you provide all the code for your HomeController? If so you are missing the Index action of the Home controller. e.g

public class HomeController : Controller
{
    public ActionResult Index()
    {

        return View();
    }

}

Right now you are redirecting to a non-existent Action which will give you an error.

You need to tell your controller what to do when the Index action of the Home controller is called by defining the Index action as I did above. You will also need to add a View that tells the controller what page to display after the Index action is called. (your home page)

This link has some really good tutorials http://www.asp.net/mvc that got me started with MVC. It may help further explain what is wrong with what you are doing.

Rondel
  • 4,811
  • 11
  • 41
  • 67
  • The issue got resolved later. See the answer here http://stackoverflow.com/questions/7167251/mock-presence-of-authorize-attribute/7170758#comment-8660724 could have been something with my GAC. Thanks for the help though. – Tim Sep 09 '11 at 07:46