TchiYuan
TchiYuan

Reputation: 4278

How does RedirectToRouteResult work?

I'm currently using RedirectToRouteResult as follow:

public void OnAuthorization(AuthorizationContext filterContext)
{
    User user = filterContext.HttpContext.Session["user"] as User;
    if (user == null || user.Role != expectedRole)
    {
        filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary {
                {"controller", _controller}, {"action", _action}
        });
    }
}

This code is in my CheckLoginAttribute class.

I intend to use it as decorator on specific controller actions for example:

[CheckLogin(RolesEnum.Member, "MyController", "MyAction")]
public JsonResult GetNews()

So basically, I'm trying to short circuit a call to GetNews() and skip the execution of the action if the user is not logged on. If the user is not logged on then I want it to redirect to another action.

Will RedirectToRouteResult redirect to the appropriate action server side without having to do a big loop through the client side (like rewritting window URL location or something like that)? Is that how it works?

Upvotes: 8

Views: 10602

Answers (3)

an phu
an phu

Reputation: 1823

Your solution is not robust and complicates the client code; Not to mention the overhead of maintain this code for all different types of client.

By returning JSON, the response status code will be 200. This means you'll need add security logic to each of your client to interpret every response to detect unauthorized access. Use the Authorize filter.

http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute(v=vs.118).aspx

NOTE:

"If an unauthorized user tries to access a method that is marked with the Authorize attribute, the MVC framework returns a 401 HTTP status code. If the site is configured to use ASP.NET forms authentication, the 401 status code causes the browser to redirect the user to the login page."

Upvotes: 0

TchiYuan
TchiYuan

Reputation: 4278

Well, I've figured it out on my own.

So basically, it wasn't "redirection" that I needed. I was looking at the wrong place to solve my problem. I knew that redirection meant that I'd have to make several client/server trips just to be able to return a json result and it didn't feel right.

It took me a while to realize that I can pass any type of result into filterContext.Result.

It's my fault. I wasn't asking the right question because I didn't completely understand the problem I was facing. After a lot of research it comes down to being really stupid.

Final solution is:

    public class CheckLoginAttribute : AuthorizeAttribute, IAuthorizationFilter
{

    private RolesEnum expectedRole;

    public CheckLoginAttribute(RolesEnum role)
    {
        expectedRole = role;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        User user = filterContext.HttpContext.Session["user"] as User;
        if (user == null || user.Role != expectedRole)
        {
            filterContext.Result = new JsonResult()
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new LoginMessage() { IsValidLogin = false }
            };
        }
    }
}

And now I can decorate my action methods with this:

[CheckLogin(RolesEnum.Admin)]

A little bit more code to avoid ASP.NET Session stealing and I'm done.

I hope this will help someone out there. Thanks.

Upvotes: 4

Jakub Konecki
Jakub Konecki

Reputation: 46008

No - RedirectXXXResult always returns HTTP 302. This is not an equivalent of Server.Transfer().

Upvotes: 1

Related Questions