所以对asp.net mvc中的身份验证非常困惑 [英] So very very confused about Authentication in asp.net mvc

查看:96
本文介绍了所以对asp.net mvc中的身份验证非常困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I come to the conclusion I need to ditch the ASP.NET Membership (for list of reasons).

现在,我真正需要的唯一一件事就是创建一个cookie(由Form Authentication完成),用于身份验证的自定义方法(完成)以及最终基于它们是否已登录或按角色进行验证.

Now really the only thing I see that I need is creating a cookie(done by Form Authentication), custom methods for authentication (done) and finally validation based on if they are logged in or by role.

我被困在最后一个.

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

I am trying to override the Authorize (attribute) but I have no clue how to do this. I looked at many examples and each one seems to be done differently then the next. I don't know why they do this or which one I should be using.

有些教程似乎在AuthorizeCore中进行身份验证,有些教程在OnAuthentication中进行身份验证.

Some tutorials seem to do the authentication in the AuthorizeCore, Some do it in the OnAuthentication.

有些使用某些AuthorizationContext东西,然后调用此基类.

Some use some AuthorizationContext thing and then call this base class.

base.OnAuthorization(filterContext);

有些似乎在其中进行缓存.

Some seem to do caching in it.

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

What I want is all the functionality the built in ones have but just hooked up to my custom tables. Like I going to have my own Role table. I need to tell it where that is and pull the stuff in.

我也不知道该怎么做或如何装饰这样的标签

Also I have no clue how to do this or how decorate the tag like this

[Authorize(Roles="test")]

参考文献:- http://darioquintana.com.ar/blogging/tag/aspnet-mvc/ asp.net mvc添加到AUTHORIZE属性 http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx

References:- 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?仅有的 OnAuthentication?
  4. 高速缓存指的是什么?喜欢 缓存角色吗?还是页面? 我不能告诉调试器 似乎每一个都运行代码 时间.

  1. Why is it sealed? If it is sealed does it not make it harder to unit test?
  2. What is filterContext?
  3. Why is no AuthorizeCore used? Only OnAuthentication?
  4. Whats the cache refering to? Like is it caching the role? Or the Page? I can't tell with the debugger it seems to run the code every single time.

缓存安全吗?

通常这样安全(即没有孔) 在其中被剥夺-有点担心 我会搞砸了,有 我网站上的一些主要漏洞).

In general is this safe(ie no holes in it to be explioted- kinda worried I will screw something up and have some major hole in my site).

推荐答案

这是一个自定义属性,可以根据您的需要工作;为角色类型使用Enum并自己使用cookie创建,这允许存储角色.

Here's a custom attribute that would work just as you want it; using an Enum for role types and using cookie creation yourself, which allows for storing of roles.

用法

  [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 */);
        }


    }

您需要将您的角色明确添加到auth cookie中,并在基本控制器中将其读回.我的实现还有其他一些您可能不希望看到的细节,因此最好在这里阅读:

you'll need to have explicitly added your roles to auth cookie and read them back in a base controller say. my implementation has other details which you might not want so maybe best to read here: http://ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html

这篇关于所以对asp.net mvc中的身份验证非常困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆