2013-02-06 149 views
2

我想允许匿名访问我的网站的根。如果我向site.com/home发出请求,它允许匿名访问。但是,如果我请求site.com/,我会看到一个登录页面。到目前为止,我已经做了以下内容:允许匿名访问MVC4操作

在web.config我授权为所有用户 “家”:

<location path="Home"> 
    <system.web> 
     <authorization> 
     <allow users="*" /> 
     </authorization> 
    </system.web> 
    </location> 

在FilterConfig.cs添加以下AuthorizeAttribute:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
     filters.Add(new System.Web.Mvc.AuthorizeAttribute()); 
    } 

My Home Index控制器动作如下所示:

[AllowAnonymous] 
    public ActionResult Index() 
    { 
     return View(); 
    } 

我的路线如下所示:

 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.MapRoute(
      name: "Zoom", 
      url: "zoom/{id}", 
      defaults: new { controller = "Zoom", action = "Index" } 
     ); 

     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 

这是否完成了路线?我完全错过了什么吗?

回答

1

你必须在属性代码中实现逻辑来过滤它。换句话说,您必须检查并查看方法/类是否使用该属性进行了注释,如果是(或根据您的方案进行相应处理),则跳过授权。

下面是一个例子:

/// <summary> 
    /// This class is used to ensure that a user has been authenticated before allowing a given method 
    /// to be called. 
    /// </summary> 
    /// <remarks> 
    /// This class extends the <see cref="AuthorizeAttribute"/> class. 
    /// </remarks> 
    public sealed class LoginAuthorize : AuthorizeAttribute 
    { 
     /// <summary> 
     /// The logger used for logging. 
     /// </summary> 
     private static readonly ILog Logger = LogManager.GetLogger(typeof(LoginAuthorize)); 

     /// <summary> 
     /// Handles the authentication check to ensure user has been authenticated before allowing a method 
     /// to be called. 
     /// </summary> 
     /// <param name="filterContext">The authorization context object.</param> 
     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      DateTime methodEntryTime = DateTime.Now; 
      Helper.LogMethodEntry(Logger, MethodBase.GetCurrentMethod(), filterContext); 

      try 
      { 
       // determine if the called method has the AllowAnonymousAttribute, which means we can skip 
       // authorization 
       bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) 
       || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true); 

       if (!skipAuthorization) 
       { 
        base.OnAuthorization(filterContext); 

        // make sure required session data is still present 
        if (string.IsNullOrWhiteSpace(filterContext.HttpContext.Session[Helper.ROLE_NAME] as string)) 
        { 
         HandleUnauthorizedRequest(filterContext); 
        } 
       } 

       Helper.LogMethodExit(Logger, MethodBase.GetCurrentMethod(), methodEntryTime); 
      } 
      catch (Exception e) 
      { 
       Helper.LogException(Logger, MethodBase.GetCurrentMethod(), e); 
       throw; 
      } 
     } 

     /// <summary> 
     /// Handles unauthorized requests. Redirects user to login page. 
     /// </summary> 
     /// <param name="filterContext">The authorization context object.</param> 
     protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
     { 
      DateTime methodEntryTime = DateTime.Now; 
      Helper.LogMethodEntry(Logger, MethodBase.GetCurrentMethod(), filterContext); 

      try 
      { 
       base.HandleUnauthorizedRequest(filterContext); 

       // redirect user to login page 
       filterContext.Result = new RedirectResult("~/Login"); 

       Helper.LogMethodExit(Logger, MethodBase.GetCurrentMethod(), methodEntryTime); 
      } 
      catch (Exception e) 
      { 
       Helper.LogException(Logger, MethodBase.GetCurrentMethod(), e); 
       throw; 
      } 
     } 
    } 
} 

然后,在Global.asax你想补充一点LoginAuthorize类,像这样:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    filters.Add(new LoginAuthorize()); 
    filters.Add(new HandleErrorAttribute()); 
} 
+0

尝试了您的建议,但它没有工作,除非我实施它不正确。如果它在我请求时发挥作用/ Home不是让根请求发送到适当的控制器/操作的问题?当我去/家时,它显示访问是正确的,因为它提供了正确的回报。 – Alex

+0

您是否在OnAuthorization方法中设置了休息以确保其正常工作?我知道这种方法可行,因为我在我的一个生产应用程序中使用它。 – dcp

1

首先,你不应该使用授权与Web表单的方式web.config。先去掉那个。 其次,通过将Authorize属性添加为全局过滤器,您基本上将Authorize属性应用于所有控制器和操作,这真的是您想要的吗? 装饰动作方法或完整的控制器更为常见。如果控制器具有授权属性,那么您仍然可以通过添加AllowAnonymous属性来允许操作方法的匿名访问,就像您已经做过的一样。

使用这种方法应该工作得很好,路线看起来不错。

相关问题