1

I'm not quite sure why I am struggling with this as I'm sure it should be simple. I've created an MVC 5 web application which is based on .net 4.5. I've enable windows authentication in the web.config as below;

<system.web>
   <Authentication mode="windows" />
</system.web>

This is working perfectly. I was actually surprised at how easy the new framework makes it. When a user navigates to my site it authenticates them and logs them in which is cool. When it cannot authenticate the user it produces a 401 error, I want to provide a custom page for this error. In order to catch the 401 I used the following pseudo code;

public class GlobalErrorAttribute : ErrorHandlerAttribute
{
     public override OnError(filterContext _context)
     {
         if(statusCode = 401)
         {
             _context.Result = RedirectTo("~/Errors/MyCustomPage");
         }
     }
}

This redirect of course requires a controller which is fine, it's very basic;

public class ErrorsController : Controller
{
     public ActionResult MyCustomPage()
     {
          return View();
     }
}

My Issue

This wonderful error page which it redirects to, throws a 401 because it is still trying to authenticate. [AllowAnonymoous] will not work as this is authorization. How do I stop MVC attempting to authenticate?

It must be easy, I can think of a common example where you would want this behavior. A public facing website might want to use windows authentication for employees on premise but allow the public to browse un-Authenticated.

How can I achieve this?

Update

When the user is not Authenticated the 401 bypasses my GlobalErrorAttribute?!? How can I turn authentication off for a page? Like it does for the custom error page?

Community
  • 1
  • 1
Heberda
  • 830
  • 7
  • 29
  • Is it a typo there in "Errors" controller name or MVC 5 allow controller name without suffixing "Controller"? – SBirthare Mar 26 '15 at 11:32
  • Sorry that's just me being lazy, I didn't copy and paste anything. Although if that was the issue I wouldn't be getting a 401 :) regards, Dan. – Heberda Mar 26 '15 at 11:35

2 Answers2

2

It is possible to specify the resource that specified configuration settings must apply to, using the <location> element in your configuration file.

More on MSDN here: <location> Element

Update:

For example, you could refine and add something like this.

<location path="Errors/MyCustomPage">
  <system.web>
    <authorization>
      <allow verbs="GET" users="*" />
    </authorization>
  </system.web>
</location>
Biscuits
  • 1,767
  • 1
  • 14
  • 22
  • I did briefly try this, although I read somewhere it was not supported in .net 4.5 and MVC 5? I try again :) Regards, Dan. – Heberda Mar 26 '15 at 12:17
  • This seems to have solved the issue, how can I apply this to more than one file? Any way to get this in an attribute? – Heberda Mar 26 '15 at 12:33
  • I'm not too sure, but I think you won't be able to specify more than one file in the path attribute. You should, however, be able to specify several of these elements - one for every file. Please remember to vote if this answers your question. – Biscuits Mar 26 '15 at 12:43
  • That seems like a massive drawback to the new Authentication. What if I have a whole controller that I don't want to authenticate on? – Heberda Mar 26 '15 at 12:45
  • I speculate you may be able to specify the root path alone, and it would apply to all resources there under. This means you can specify "Errors" alone (without the specific "MyCustomPage" action) and have the configuration settings apply for all actions abroad. – Biscuits Mar 26 '15 at 12:50
  • Thanks Biscuits, the solution is the equivalent of polishing a turd... the way in which MVC handles deny is bad, it's just trying to make it a little better. At the moment I am only allowing access to one file so all is good. Thanks :) – Heberda Mar 26 '15 at 14:41
1

Update Enable anonymous authentication for the application through the command line appcmd set config /section:anonymousAuthentication /enabled:true

lloyd
  • 1,683
  • 2
  • 19
  • 23
  • It's not authorization that is causing the 401, it's authentication. – Heberda Mar 26 '15 at 12:18
  • Ah, apologies. Lets have another look. – lloyd Mar 26 '15 at 12:24
  • have you enabled anonymous authentication for the [application](https://technet.microsoft.com/en-us/library/cc731244%28v=ws.10%29.aspx) through the command line appcmd set config /section:anonymousAuthentication /enabled:true – lloyd Mar 26 '15 at 12:37
  • I have no idea what you are talking about, however I do have Anonymous Authentication turned on in IIS. The previous answer solved the issue but this is only for one page which seems like a rather poor solution. I appreciate the answer though, maybe something I should look into. – Heberda Mar 26 '15 at 12:43
  • no problem, I'll add to the answer if I find a solution for more than one page. – lloyd Mar 26 '15 at 16:58
  • Thank you, it still strikes me as weird that you can override some kind of AuthenticationAttribute?! – Heberda Mar 27 '15 at 09:54
  • 1
    It is a little weird, however they have to allow for developers to decide on the trade offs between confidentiality, integrity and availability they want to [adopt](https://www.simple-talk.com/dotnet/.net-framework/creating-custom-oauth-middleware-for-mvc-5/). – lloyd Mar 27 '15 at 17:06