4

This may be pie in the sky but I'm wondering if the following could be accomplished with a custom controller attribute.

For a majority of my controllers, I will be passing in an URL parameter called "r" to each action within the controller. "r" is tied to a race id in the races table in my database.

What I would like to happen is that any time a controller action is invoked, it'll automatically check for the existence of "r", query the database to make sure "r" belongs to the logged in user and set a viewbag variable called ViewBag.RaceId equal to "r".

If any of those conditions aren't met, it'll redirect them back to the login page.

I'm trying to make my code as DRY as possible.

Any guidance would be greatly appreciated.

1 Answer 1

6

You could write a custom Authorize attribute:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var isAuthorized = base.AuthorizeCore(httpContext);
        if (isAuthorized)
        {
            var request = httpContext.Request;
            // Fetch "r" from the route data or request
            var r = request.RequestContext.RouteData.Values["r"] 
                ?? request["r"];
            var currentUser = httpContext.User.Identity.Name;
            if (!CheckIfRBelongsToTheCurrentLoggedInUser(currentUser, r))
            {
                return false;
            }
        }
        return isAuthorized;
    }
}

Now all that's left is to decorate your controllers/actions with this custom attribute:

[MyAuthorize]
public ActionResult Foo()
{
    //...
}

And if you wanted to put something into the ViewBag you could temporarily store it in the httpContext.Items inside the AuthorizeCore method in case of success and then override the OnAuthorization method as well and check for the presence of this item in the context. If it is present you could store it in the filterContext.Controller.ViewBag.

Sign up to request clarification or add additional context in comments.

3 Comments

Pure Awesome. One question though regarding the ViewBag. In my custom attribute I added: httpContext.Items.Add("RaceId", r.ToString()); and in my override for OnAuthorization I added filterContext.Controller.ViewBag.RaceId = filterContext.HttpContext.Items["RaceId"]; is that correct? New to overriding OnAuthorization.
Nevermind. I had ilterContext.Controller.ViewBag.RaceId = filterContext.HttpContext.Items["RaceId"] before base.OnAuthorization(filterContext); It works now!
Note anyone who's using Darin's suggestion to pass data through httpContext.Items: you need to have OnAuthorization call base.OnAuthorization(filterContext) before checking httpContext.Items. I couldn't get it to work until I did this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.