Asp.net mvc 4 ASP.NET MVC4自定义授权

Asp.net mvc 4 ASP.NET MVC4自定义授权,asp.net-mvc-4,attributes,authorize,Asp.net Mvc 4,Attributes,Authorize,我已经在ASP.NET MVC4中通过重写AuthorizeAttribute来实现自定义授权属性。我想在某些控制器和控制器操作上实现这一点,以使它们拒绝未经授权的请求,如未登录用户的请求和/或某些权限问题。我不想实现asp.net成员身份和授权,代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.

我已经在ASP.NET MVC4中通过重写
AuthorizeAttribute
来实现自定义授权属性。我想在某些控制器和控制器操作上实现这一点,以使它们拒绝未经授权的请求,如未登录用户的请求和/或某些权限问题。我不想实现asp.net成员身份和授权,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Diagnostics.CodeAnalysis;
using System.Security.Principal;
using System.Web.Mvc.Properties;
using System.Web.Routing;

namespace TestMVC4
{
    public sealed class AuthorizeUserAttribute : AuthorizeAttribute
    {
        private static readonly string[] _emptyArray = new string[0];
        string activities;
        string[] activitiesList = _emptyArray;

        string roles;
        string[] rolesList = new string[0];

        /// <summary>
        /// Gets or sets list of authorized activities 
        /// </summary>
        public string Activities
        {
            get { return activities ?? String.Empty; }
            set
            {
                activities = value;
                activitiesList = SplitString(value);
            }
         }

         public string CRole
         {
            get { return roles ?? String.Empty; }
            set
            {
                 roles = value;
                 rolesList = SplitString(value);
             }
         }

        /// <summary>
        /// Authorization initial call
        /// </summary>
        /// <param name="filterContext">Filter context</param>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
            {
                // If a child action cache block is active, we need to fail immediately, even if authorization
                // would have succeeded. The reason is that there's no way to hook a callback to rerun
                // authorization before the fragment is served from the cache, so we can't guarantee that this
                // filter will be re-run on subsequent requests.
                //throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
                throw new InvalidOperationException("Cannot use within child action cache.");
            }

            bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)
                                     || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);

            if (skipAuthorization)
            {
                return;
            }

            if (AuthorizeCore(filterContext.HttpContext))
            {
                // ** 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 */);
            }
            else
            {
                HandleUnauthorizedRequest(filterContext);
            }
        }

        /// <summary>
        /// Main method for overriding custom authorization for application
        /// </summary>
        /// <param name="httpContext">Current execution context</param>
        /// <returns>True/False whether user is authorized for given activity or not respectively</returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            //Verify sessionuser roles
            if (rolesList != null)
            {
                String sessionRole = Convert.ToString(httpContext.Session["MyRole"]);

                foreach (String role in rolesList)
                {
                    if (role == sessionRole)
                        return true;
                }
            }

            //IPrincipal user = httpContext.User;
            //if (!user.Identity.IsAuthenticated)
            //{
            //    return false;
            //}

            //if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
            //{
            //    return false;
            //}

            //if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
            //{
            //    return false;
            //}

            return false;
        }

        /// <summary>
        /// Overriden method for handling unauthorized request routing
        /// </summary>
        /// <param name="filterContext">Authorization context for which the request has been made</param>
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
            filterContext.Result = new HttpUnauthorizedResult();

            //filterContext.RequestContext.RouteData;

            //filterContext.Result = new RedirectToRouteResult(
            //        new RouteValueDictionary(
            //            new
            //            {
            //                controller = "Error",
            //                action = "Unauthorised"
            //            })
            //        );
        }

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

        protected HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            bool isAuthorized = AuthorizeCore(httpContext);
            return (isAuthorized) ? HttpValidationStatus.Valid : HttpValidationStatus.IgnoreThisRequest;
        }

        /// <summary>
        /// Splits the string on commas and removes any leading/trailing whitespace from each result item.
        /// </summary>
        /// <param name="original">The input string.</param>
        /// <returns>An array of strings parsed from the input <paramref name="original"/> string.</returns>
        string[] SplitString(string original)
        {
            if (String.IsNullOrEmpty(original))
            {
                return _emptyArray;
            }

            var split = from piece in original.Split(',')
                        let trimmed = piece.Trim()
                        where !String.IsNullOrEmpty(trimmed)
                        select trimmed;
            return split.ToArray();
        }
      }
}  
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Web.Mvc;
使用System.Diagnostics.CodeAnalysis;
使用System.Security.Principal;
使用System.Web.Mvc.Properties;
使用System.Web.Routing;
命名空间TestMVC4
{
公共密封类AuthorizeUserAttribute:AuthorizeAttribute
{
私有静态只读字符串[]\u emptyArray=新字符串[0];
弦乐活动;
字符串[]活动列表=\u emptyArray;
字符串角色;
字符串[]角色列表=新字符串[0];
/// 
///获取或设置授权活动的列表
/// 
公益活动
{
获取{返回活动??String.Empty;}
设置
{
活动=价值;
活动列表=拆分字符串(值);
}
}
公共弦乐
{
获取{返回角色??字符串.Empty;}
设置
{
角色=价值;
角色列表=拆分字符串(值);
}
}
/// 
///授权初始呼叫
/// 
///过滤上下文
授权时的公共覆盖无效(AuthorizationContext filterContext)
{
如果(filterContext==null)
{
抛出新ArgumentNullException(“filterContext”);
}
if(OutputCacheAttribute.IsChildActionCacheActive(filterContext))
{
//如果子操作缓存块处于活动状态,则需要立即失败,即使授权失败
//可能已经成功了。原因是无法钩住回调以重新运行
//在从缓存提供片段之前进行授权,因此我们不能保证
//过滤器将在后续请求中重新运行。
//抛出新的InvalidOperationException(MvcResources.AuthorizationAttribute_不能在HildActionCache中使用);
抛出新的InvalidOperationException(“无法在子操作缓存中使用”);
}
bool skipAuthorization=filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute),inherit:true)
||filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute),inherit:true);
如果(授权)
{
返回;
}
if(AuthorizeCore(filterContext.HttpContext))
{
//**重要**
//因为我们在操作级别执行授权,所以授权代码会运行
//在输出缓存模块之后。在最坏的情况下,这可能允许授权用户
//为了使页面被缓存,随后将向未经授权的用户提供
//缓存页面。我们通过告诉代理不要缓存敏感页面来解决这个问题,
//然后,我们将自定义授权代码挂接到缓存机制中,以便
//关于是否应从缓存中提供页面的最终决定权。
HttpCachePolicyBase cachePolicy=filterContext.HttpContext.Response.Cache;
SetProxyMaxAge(新的时间跨度(0));
AddValidationCallback(CacheValidateHandler,null/*data*/);
}
其他的
{
HandleUnauthorizedRequest(filterContext);
}
}
/// 
///覆盖应用程序自定义授权的主要方法
/// 
///当前执行上下文
///True/False用户是否分别获得给定活动的授权
受保护的覆盖bool AuthorizeCore(HttpContextBase httpContext)
{
if(httpContext==null)
{
抛出新ArgumentNullException(“httpContext”);
}
//验证会话用户角色
如果(角色列表!=null)
{
字符串sessionRole=Convert.ToString(httpContext.Session[“MyRole”]);
foreach(角色列表中的字符串角色)
{
如果(角色==会话角色)
返回true;
}
}
//IPrincipal user=httpContext.user;
//如果(!user.Identity.IsAuthenticated)
//{
//返回false;
//}
//if(_usersSplit.Length>0&!_usersSplit.Contains(user.Identity.Name,StringComparer.OrdinalIgnoreCase))
//{
//返回false;
//}
//if(_rollessplit.Length>0&!_rollessplit.Any(user.IsInRole))
//{
//返回false;
//}
返回false;
}
/// 
///用于处理未授权请求路由的重写方法
/// 
///为其发出请求的授权上下文
受保护的覆盖无效HandleUnauthorizedRequest(授权上下文筛选器上下文)
{
//返回HTTP 401-请参阅HttpUnauthorizedResult.cs中的注释。
filterContext.Result=新的HttpUnauthorizedResult();
//filterContext.RequestContext.RoutedData;
//filterContext.Result=新的RedirectToRouteResult(
//新RouteValueDictionary(
//新的
//            {
 Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(userName),
                                new string[] {"Roles goes here"});
User.Identity.Name
public class BasicHttpAuthorizeAttribute : AuthorizeAttribute
{

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (Thread.CurrentPrincipal.Identity.Name.Length == 0)
        {
                    if (ValidateUser(userName, password))
                        Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(userName, "Basic"),
                            new string[] {});

        }
        return base.IsAuthorized(actionContext);
    }
}