0

I have a super simple Authentication Attribute that I'm trying to implement in an ASP.NET MVC 5 application and I'm having some trouble. I want the attribute to be applied globally, except for specific actions within a controller (for example the login form and the home page).

I've tried decorating the action with the [OverrideAuthentication] attribute with no luck. It gives me a redirect loop error because the application is still running the authentication on the login form, and keeps trying to redirect back to the login form over and over.

Has anyone else seen this behaviour? Any idea what I've stuffed up here?

By way of example, I've created a super simple filter that is currently unimplemented:

public class BasicAuthenticationAttribute
    : ActionFilterAttribute, IAuthenticationFilter
{

    public void OnAuthentication(AuthenticationContext filterContext)
    {
        throw new NotImplementedException();
    }

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
    {
        throw new NotImplementedException();
    }
}

If I decorate my controller/action like this:

[BasicAuthentication]
public class AccountController : Controller
{
    [HttpGet]
    [OverrideAuthentication]
    public ActionResult Login()
    {
        return View();
    }
}

I get a not implemented exception when I navigate to the Login action, even though that action shouldn't be running the authentication code at all. Have I misunderstood how overrides are supposed to work?

Nick Coad
  • 3,346
  • 4
  • 25
  • 61
  • Don't you just want [AllowAnonymous] against the login action? – Brendan Green Feb 25 '14 at 00:58
  • Nope, AllowAnonymous is an authorization attribute, something that occurs after authentication has already taken place and says that the user is authenticated as an "Anonymous" type user and is allowed to view this page. What I'm after is something that says NO authentication should take place at all (which I'm sure is what the override filter should be doing) – Nick Coad Feb 25 '14 at 00:59
  • Are you sure your attribute name is [OverrideAuthentication]??? – Gjohn Feb 25 '14 at 02:12

1 Answers1

3

I think you have confused authentication with authorization (as many people do). It doesn't make sense to make a [BasicAuthenticationAttribute] and register it globally, because authentication only happens upon login, not on every request.

Authorization is what takes place after the user has logged in to check whether the user has the required privileges to do a specific action, and it makes sense to do authorization globally. Authorization in MVC is handled by the [AuthorizeAttribute] and you can inherit it if you need to customize the way the authorization check is done. You can also register it as a global filter.

The [AllowAnonymousAttribute] works in conjunction with [AuthorizeAttribute], and basically tells it to skip the authorization check. It should also be noted that the [AllowAnonymousAttribute] will have no effect unless it is used with the [AuthorizeAttribute].

NightOwl888
  • 51,095
  • 20
  • 122
  • 194
  • I think you're right, do you have any reasonably comprehensive resources for this? Things changed a lot around authorization in MVC5 and there aren't really any good books out yet on the topic. Any ideas? – Nick Coad Feb 25 '14 at 22:57
  • 1
    This article seems to provide some good information: http://www.dotnetcurry.com/showarticle.aspx?ID=957. I agree that Microsoft doesn't document new features very well before they are released, you usually have to wait several months to make heads or tails of them. – NightOwl888 Feb 27 '14 at 03:46
  • Here is a great way to override authorization http://stackoverflow.com/a/32661139/1477388 – user1477388 Nov 18 '16 at 20:30