防止访问.net MVC中的特定区域

本文关键字:区域 MVC 访问 net | 更新日期: 2023-09-27 18:03:51

MVC3网站的管理部分被创建为一个Area。然后将以下代码放入Web.config

<location path="Admin">
<system.web>
  <authentication mode="Forms">
    <forms loginUrl="~/Admin/Login/Login" timeout="5000" defaultUrl="~/Admin/Login/Redirect" />
  </authentication>
  <authorization>
    <deny users="?"/>
  </authorization>
</system.web>
</location>

但是会抛出错误

解析器错误消息:使用注册为的section是错误的allowDefinition='MachineToApplication'超出应用程序级别。这错误可能是由于虚拟目录未配置为

源错误:

Line 44:   <location path="Admin">
Line 45:     <system.web>
Line 46:       <authentication mode="Forms">
Line 47:         <forms loginUrl="~/Admin/Login/Login" timeout="5000" defaultUrl="~/Admin/Login/Redirect" />
Line 48:       </authentication>

防止访问.net MVC中的特定区域

不能覆盖特定子文件夹的<authentication>节点。这是不支持的。如果你想在你的区域拥有一个不同的登录页面,你可以编写一个自定义的[Authorize]属性,然后用它来装饰区域中的所有控制器动作。其思想是只覆盖HandleUnauthorizedRequest方法并重定向到所需的登录页面。

例如:

public class AdminAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var routeValues = new RouteValueDictionary(new
        {
            controller = "login",
            action = "login",
            area = "admin"
        });
        filterContext.Result = new RedirectToRouteResult(routeValues);
    }
}

至于你的网。

<authentication>节点必须直接配置在<system.web>节下,而不是在<location>节内。

我已经试过解释

如果您的应用程序包含,多个区域,当应用程序运行时,所有区域都被注册。使登录用户可以访问每个区域。

但是如果你想只允许访问特定区域,那么你需要重写默认的区域注册过程。

在这个过程中,我们删除了所有属于每个区域的路由

在(RouteTable.Routes

。计数> 0)

RouteTable.Routes.RemoveAt (0);

之后,我们只允许那些我们想要允许登录用户的区域,我们使用

MvcApplication app = (MvcApplication)HttpContext.ApplicationInstance;
RouteCollection existingcoll = outeCollection)app.Application["ExistingRoutecolling"];
foreach (Route _route in existingcoll)
 {
    // allow only those routes , which belongs to the area which you want allow to access the login user
    if (_route.Url == "Admin/{controller}/{action}/{id}")
        RouteTable.Routes.Add((RouteBase)_route);       
    // re-register routes again
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    // now redirect with expected action
    return RedirectToAction("controller", "action", new { area = "Admin" });
}
public class MvcApplication : System.Web.HttpApplication
 {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            RouteCollection existingcoll = new RouteCollection();
            foreach (Route _route in RouteTable.Routes)
                existingcoll.Add((RouteBase)_route);
            //keep all default registerd routes in Asp Application object  
            Application["ExistingRoutecolling"] = existingcoll;
        }
}
//after login when user called first action to render dashboard, you can add logic there
 public ActionResult ModuleDashboard
 {
     //get default registerd routes from Asp Application object which we stored in  Application_Start() method 
    MvcApplication app = (MvcApplication)HttpContext.ApplicationInstance;
    RouteCollection existingcoll = (RouteCollection)app.Application["ExistingRoutecolling"];
    // remove all register routes, by default those are registered by application object
    while (RouteTable.Routes.Count > 0)
        RouteTable.Routes.RemoveAt(0);
    //navigate each route from collection and add in actual application route collection object         
     foreach (Route _route in existingcoll)
     {
        // allow only those routes , which belongs to the area which you want allow to access the login user
        if (_route.Url == "Admin/{controller}/{action}/{id}")
            RouteTable.Routes.Add((RouteBase)_route);       
        // re-register routes again
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        // now redirect with expected action
        return RedirectToAction("controller", "action", new { area = "Admin" });
    }
 }