【问题标题】:So very very confused about Authentication in asp.net mvc对asp.net mvc中的身份验证非常困惑
【发布时间】:2009-09-28 06:09:45
【问题描述】:

我得出的结论是我需要放弃 ASP.NET Membership(原因列表)。

现在我真正看到的唯一需要的是创建一个 cookie(由 Form Authentication 完成)、用于身份验证的自定义方法(完成),最后根据他们是否登录或按角色进行验证。

我被最后一个卡住了。

我正在尝试覆盖Authorize(属性),但我不知道如何执行此操作。我查看了许多示例,每个示例似乎都与下一个示例不同。我不知道他们为什么这样做或我应该使用哪一个。

有些教程好像在AuthorizeCore做认证,有些在OnAuthentication做。

有些人使用一些AuthorizationContext 的东西,然后调用这个基类。

base.OnAuthorization(filterContext);

有些似乎在里面做缓存。

我想要的是内置功能的所有功能,但只是连接到我的自定义表格。就像我将拥有自己的角色表一样。我需要告诉它在哪里,然后把东西拉进去。

我也不知道如何做到这一点或如何像这样装饰标签

[Authorize(Roles="test")]

参考资料:- http://darioquintana.com.ar/blogging/tag/aspnet-mvc/ asp.net mvc Adding to the AUTHORIZE attribute http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx

编辑

这就是我现在所拥有的。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public sealed class AuthorizeAttributeCustom : AuthorizeAttribute
    {

        public string Roles { get; set; }


        private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
        {
            validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {

            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                // auth failed, redirect to login page
                filterContext.Result = new HttpUnauthorizedResult();
                return;
            }

            DataClasses1DataContext test = new DataClasses1DataContext();
            var name = filterContext.HttpContext.User.Identity.Name;
            var user = test.User2s.Where(u => u.userName == name).FirstOrDefault();
            var role = test.Roles.Where(u => u.UserId == user.userId).Select(u => u.Role1).FirstOrDefault();

            string[] split = Roles.Split(',');

            if (split.Contains(role) == true)
            {
                // is authenticated and is in the required role
                SetCachePolicy(filterContext);
                return;
            }
            filterContext.Result = new HttpUnauthorizedResult();
        }

        private void SetCachePolicy(AuthorizationContext filterContext)
        {
            // ** IMPORTANT **
            // Since we're performing authorization at the action level, the authorization code runs
            // after the output caching module. In the worst case this could allow an authorized user
            // to cause the page to be cached, then an unauthorized user would later be served the
            // cached page. We work around this by telling proxies not to cache the sensitive page,
            // then we hook our custom authorization code into the caching mechanism so that we have
            // the final say on whether a page should be served from the cache.
            HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
            cachePolicy.SetProxyMaxAge(new TimeSpan(0));
            cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
        }
    }

突出问题

  1. 为什么要密封?如果是密封的 它不会使团结变得更加困难吗 测试?
  2. 什么是 filterContext?
  3. 为什么没有使用 AuthorizeCore?仅有的 开启身份验证?
  4. 缓存指的是什么?喜欢 是缓存角色吗?还是页面? 我不能用调试器告诉它 似乎每次都运行代码 时间。

  5. 缓存安全吗?

  6. 一般来说这是安全的(即没有孔 在其中被利用-有点担心 我会把事情搞砸并拥有 我的网站上有一些重大漏洞)。

【问题讨论】:

    标签: c# .net asp.net-mvc authorization


    【解决方案1】:

    这是一个自定义属性,可以按照您的意愿工作;对角色类型使用枚举并自己使用 cookie 创建,这允许存储角色。

    用法

      [AuthorizeAttributeCustom(RoleRequired = GoodRoles.YourRoleTypeHere)]
    

    属性代码:

    //http://stackoverflow.com/questions/977071/redirecting-unauthorized-controller-in-asp-net-mvc/977112#977112
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
        public sealed class AuthorizeAttributeCustom : AuthorizeAttribute
        {
    
            /// <summary>
            /// The name of the view to render on authorization failure.  Default is "Error".
            /// </summary>
            public string ViewName { get; set; }
            public ViewDataDictionary ViewDataDictionary { get; set; }
            public DeniedAccessView DeniedAccessView { get; set; }
    
            private GoodRoles roleRequired = GoodRoles.None;
            public GoodRoles RoleRequired { get{ return roleRequired;} set{ roleRequired = value;} } // this may evolve into sets and intersections with an array but KISS
    
            public AuthorizeAttributeCustom()
            {
                ViewName = "DeniedAccess";
                DeniedAccessView = new DeniedAccessView
                                       {
                                           FriendlyName = "n/a",
                                           Message = "You do not have sufficient privileges for this operation."
                                       };
                ViewDataDictionary = new ViewDataDictionary(DeniedAccessView);
            }
    
            private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
            {
                validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
            }
    
    
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
    
                if (filterContext == null)
                {
                    throw new ArgumentNullException("filterContext");
                }
    
                if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
                {
                    // auth failed, redirect to login page
                    filterContext.Result = new HttpUnauthorizedResult();
                    return;
                }
    
                if (RoleRequired == GoodRoles.None || filterContext.HttpContext.User.IsInRole(RoleRequired.ToString()))
                {
                    // is authenticated and is in the required role
                    SetCachePolicy(filterContext);
                    return;
                }
    
                filterContext.Result = new ViewResult { ViewName = ViewName, ViewData = ViewDataDictionary };
            }
    
            private void SetCachePolicy(AuthorizationContext filterContext)
            {
                // ** IMPORTANT **
                // Since we're performing authorization at the action level, the authorization code runs
                // after the output caching module. In the worst case this could allow an authorized user
                // to cause the page to be cached, then an unauthorized user would later be served the
                // cached page. We work around this by telling proxies not to cache the sensitive page,
                // then we hook our custom authorization code into the caching mechanism so that we have
                // the final say on whether a page should be served from the cache.
                HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
                cachePolicy.SetProxyMaxAge(new TimeSpan(0));
                cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
            }
    
    
        }
    

    您需要明确地将您的角色添加到身份验证 cookie 并在基本控制器中读回它们。我的实现还有其他你可能不想要的细节,所以最好在这里阅读:http://ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html

    【讨论】:

    • 你能解释一下吗?比如chache是​​为了什么?这是页面还是角色? filterContext 有什么用?
    • 我也是通过枚举通过这个唯一的方法吗?我不能让它看起来像内置的?因为我不确定这将如何影响单元测试?现在我查看标签是否存在并检查它们的角色字符串包含的内容。如果它包含我期望的角色,那么它就会通过。我还注意到它也不使用 AuthorizeCore 方法。为什么不呢?
    • 也是现在这一行的方式“filterContext.HttpContext.User.IsInRole(RoleRequired.ToString())”从哪里拉角色? VS2008 Intellisense 甚至没有 IsInRole 的东西。我会认为我必须通过数据库请求来执行此操作。
    • 另外一件事,多个角色怎么样?我有一些方法 2 或更多的角色。我不确定如何通过这个角色传递多个角色。
    • SetCachePolicy() 方法是怎么回事?为什么需要它?不能全局设置 OutputCacheAttribute 来禁用缓存吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多