2

サイトのルートへの匿名アクセスを許可しようとしています。site.com/home にリクエストすると、匿名アクセスが許可されます。ただし、site.com/ をリクエストすると、ログイン ページが表示されます。これまでのところ、次のことを行っています。

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

これはルートで達成されますか?私は何かを完全に見逃していますか?

4

2 に答える 2

2

You have to implement the logic in the Attribute code to filter it. In other words, you have to check and see if the method/class is annotated with the attribute and then skip authorization if it is (or handle accordingly for your scenario).

Here's an example:

    /// <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;
            }
        }
    }
}

Then, in Global.asax you would add this LoginAuthorize class, like this:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new LoginAuthorize());
    filters.Add(new HandleErrorAttribute());
}
于 2013-02-06T18:07:24.460 に答える
1

まず第一に、web.config で Web フォームの承認方法を使用しないでください。まずそれを取り除きます。2 つ目は、Authorize 属性をグローバル フィルターとして追加することで、基本的にすべてのコントローラーとアクションに Authorize 属性を適用していることになります。アクション メソッドまたは完全なコントローラーを装飾する方が一般的です。コントローラーに authorize 属性がある場合でも、既に行ったように、AllowAnonymous 属性を追加することで、アクション メソッドへの匿名アクセスを許可できます。

このアプローチを使用すると、問題なく動作するはずです。ルートは見栄えがします。

于 2013-02-06T21:17:13.007 に答える