Deny direct URL access to action method

2020-05-23 19:36发布

问题:

I'm trying to find a way to deny any direct access to my action methods. Basically what I want my users to click on links to navigate instead of typing the URL directly into the address bar in their browsers.

Now I know this can be done by checking the urlreferrer in the request object but this is kind of unreliable and weak because the urlreferrer can easily be modified and some of the security suites actually remove it from the request.

So does any of you know of a way to do this in asp.net mvc3?

回答1:

Below is the code for the NoDirectAccessAttribute method to restrict direct access to any class or action method that applies the NoDirectAccess attribute

using System;
using System.Web.Mvc;
using System.Web.Routing;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class NoDirectAccessAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.UrlReferrer == null || 
                    filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
            {
            filterContext.Result = new RedirectToRouteResult(new
                           RouteValueDictionary(new { controller = "Home", action = "Index", area = "" }));  
        }
    }
}

Use the action filter as follows for any controller or action method where you don't want user to request it directly

[NoDirectAccess]
public ActionResult IsUsernameUnique()

In the example above, any direct access to the IsUsernameUnique action method will automatically redirect the user to the Home/Index action method.



回答2:

i am not sure but maybe this can help you Consider we have a page with this url

www.yoursite.com/home.aspx

To avoid your user to directly browse this page you can rewrite you url like this

www.yoursite.com/fdmf489ruv30/home.aspx

and in this url the part "fdmf489ruv30" is a unique string that you created it on session_start and will destroy it on session_end



回答3:

It is impossible to securely ensure that an authorized user CANNOT spoof a valid request.
After all, if the browser can create a "valid request", then so can an authorized user!

However, this is an unusual requirement, and I'm interested to know what's the motivation behind it?

There are, however, a number of ways to make it harder to spoof the request.
Since no methods will be completely secure, you can try to obfuscate and make it tedious for someone to spoof your requests.

As others have suggested, you could create a random "token" per session and require it in the URL (either as a path or as a querystring).

It would be even better to use JavaScript for this. Render a hidden input with this "token". Then, intercept each link's click event, append the "token" value to the URL, then navigate to the URL.

You can enhance the JavaScript to somehow "process" your token before using it, and minify your JavaScript to obfuscate it ... this would definitely deter even the above-average users from tinkering with your URLs.

There are tons of possible solutions, but the "right" solution really depends on what specific behavior you are trying to prevent.



回答4:

Use this code in Global.asax.cs and Call [NoDirectAccess] to all controllers

    //Prevent direct URL access: Call [NoDirectAccess] to all controllers to block
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class NoDirectAccessAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.UrlReferrer == null ||
                        filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
            {
                filterContext.Result = new RedirectToRouteResult(new
                               RouteValueDictionary(new { controller = "Home", action = "Login", area = "" }));
            }
        }
    }


回答5:

A quick way of doing that is to set a session containing a random number in the action which is redirecting, also pass the random number as a parameter to the other action.

Inside the other action(redirected one), compare the value of the session with the parameter of the action. If values are equal, the user is getting there by pressing button, otherwise, the user gets there by changing the URL. Hope it helps.

question on Stackoverflow