How to intercept 401 from Forms Authentication in ASP.NET MVC?

夙愿已清 提交于 2019-12-03 02:11:24

I found a workable solution.

401 redirect by FormsAuthenticationModule occurs during EndRequest. Since during event processing Modules are invoked before global.asax, we can override the status code after FormsAuthenticationModule has had its grubby hands on the request.

In my custom AuthorizationFilter, I set HttpContext.Items["PermissionDenied"] to true and then in my global.asax EndRequest, I flip the status code from 200 to 401. Then I Server.Transfer to my custom PermissionDenied view.

I would still prefer FormsAuthenticationModule itself was updated to handle this scenario but I think this is not too hackish that I think I can live with it.

Obviously, you can change how you signal that global.asax should flip the status code. I just tried setting the status code to something like 511 and used that as the condition rather than HttpContext.Items and that worked as well. I guess as long the proper status code goes out the door, the ASP.NET engine doesn't care.

HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true;

I agree the default behavior is wrong, especially considering Ajax requests. I hope to see some sort of solution in MVCv3 (fingers crossed).

The only way I know to accomplish this is to remove the Authentication section of the web.config, this is what ASP.NET looks for to redirect unauthorized requests. You can not disable this "feature" to my knowledge. If you have an authentication section you WILL be redirected to the login url if ASP.NET ever encounters a 401 status code.

But by removing this you have some other problems. If you ever want the user to be redirected to the login page for non-ajax requests, you will need to implement your own AuthorizeAttribute and use custom settings to determine where to redirect to. Also, anything else in the Authentication section would probably have to be re-implemented by you as well. Not a very practical solution in complicated sites.

I haven't done this myself, I settled for returning a 403 instead. It's annoying not having the proper HttpCode returned, but it's better than any other solution I've found so far.

Robaticus

You might want to look here: ASP.NET MVC Custom Error Handling Application_Error Global.asax?

You should be able to catch the 401 and route to a custom action at that point. We're doing this for 404 and other exceptions in our code, and it is working quite nicely.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!