2013-03-13 17 views
0

MVC3網站的管理部分創建爲區域。然後我把下面的代碼在Web.config防止訪問.Net MVC中的特定區域

<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> 

然而,它拋出一個錯誤

Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.

源錯誤:

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> 

回答

0

不能覆蓋特定的子文件夾的<authentication>節點。這根本不受支持。如果你想爲你的區域設置一個不同的登錄頁面,你可以編寫一個自定義的[Authorize]屬性,然後用它修飾Area中的所有控制器動作。這個想法是隻覆蓋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); 
    } 
} 

並儘可能你的web.config而言,<authentication>節點必須直接下<system.web>部分,而不是內部的<location>部分配置。

+0

我只需要密碼保護區域的管理目錄。我應該如何繼續。請指導。 – Ajoe 2013-03-13 07:31:07

+1

您可以編寫自定義授權屬性。根據你想存儲用戶數據的位置,你也可以啓用['Basic Authentication'](http://en.wikipedia.org/wiki/Basic_access_authentication)。 – 2013-03-13 07:31:50

-1
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" }); 
    } 

} 
+0

請解釋一下你的代碼以及爲什麼它是一個解決方案 – acostela 2016-06-23 13:04:22

0

我試圖解釋

如果您的應用程序包含多個區域, 當應用程序運行,所有區域被註冊。 ,以便登錄用戶可以訪問每個區域。

但是,如果你想允許只訪問特定區域,那麼你需要覆蓋默認區域註冊過程。

在這個過程中,我們刪除,所有的路由屬於每個區

而(RouteTable.Routes.Count> 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" }); 
}