• MVC Dynamic Authorization--示例市在Action前进行的验证,应提前到Auth过滤器


    Introduction

    In MVC the default method to perform authorization is hard coding the "Authorize" attribute in the controllers, for each action, in this article I will explain a simple way  to implement "Dynamic Authorization" with the ability to assign permissions for actions to roles or users.  

    Using the code 

    First I will explain my user authentication and role assigning model, I have used Forms Authentication this scenario, here is my sample login action: 

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginModel model, string returnUrl)
    {
        //sample data
        Dictionary<string, string> users = new Dictionary<string, string>();
        users.Add("admin", "admin-pass");
        
        string roles;
    
        if (users[model.UserName] == model.Password)
        {
            Session["User"] = model.UserName;
            roles = "admin;customer";                
            // put the roles of the user in the Session            
            Session["Roles"] = roles;
    
            HttpContext.Items.Add("roles", roles);
    
            //Let us now set the authentication cookie so that we can use that later.
            FormsAuthentication.SetAuthCookie(model.UserName, false);
    
            //Login successful lets put him to requested page
            string returnUrl = Request.QueryString["ReturnUrl"] as string;
    
            return RedirectToLocal(returnUrl);
    
            if (returnUrl != null)
            {
                Response.Redirect(returnUrl);
            }
            else
            {
                //no return URL specified so lets kick him to home page
                Response.Redirect("Default.aspx");
            }
        }
        else
        {
            // If we got this far, something failed, redisplay form
            ModelState.AddModelError("", 
              "The user name or password provided is incorrect");
            return View(model);
        }
    }

    All the actions that need authentication have to be loaded in a list, and also all of the roles and actions that each role has access to, I have put some sample code  to simulate them "AllRoles" and "NeedAuthenticationActions". Then we need to create a base class for controllers in which I have overridden the OnActionExecuting method, in which the user will be authorized based on its current role and whether he/she has logged in or not, the action may also has no need to be authorized.

    public class ControllerBase : Controller
    {
    private string ActionKey;
    
    //sample data for the roles of the application
    Dictionary<string, List<string>> AllRoles = 
               new Dictionary<string, List<string>>();
    
    protected void initRoles()
    {
        AllRoles.Add("role1", new List<string>() { "Controller1-View", 
          "Controller1-Create", "Controller1-Edit", "Controller1-Delete" });
        AllRoles.Add("role2", new List<string>() { "Controller1-View", "Controller1-Create" });
        AllRoles.Add("role3", new List<string>() { "Controller1-View" });
    }
    //sample data for the pages that need authorization
    List<string> NeedAuthenticationActions = 
      new List<string>() { "Controller1-Edit", "Controller1-Delete"};  
    
    
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        ActionKey = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName +
                           "-" + filterContext.ActionDescriptor.ActionName;
                    
        string role = Session["Roles"].ToString();//getting the current role
        if (NeedAuthenticationActions.Any(s => s.Equals(ActionKey, StringComparison.OrdinalIgnoreCase)))
        {
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                string redirectUrl = string.Format("?returnUrl={0}", 
                        filterContext.HttpContext.Request.Url.PathAndQuery);
                filterContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl + redirectUrl, true);
            }
            else //check role
            {
                if (!AllRoles[role].Contains(ActionKey))
                {
                    filterContext.HttpContext.Response.Redirect("~/NoAccess", true);
                }
            }
        }
    }

    Points of Interest

  • 相关阅读:
    好久没来园子里转了,最近在学ssh,有个小问题提出来
    ClearType使用的问题
    Metro中访问特定设备的方法
    UMDF驱动程序快速上手
    关于GPS使用上的一个怪异问题
    一个不能创建WINCE6.0工程的问题
    Metro开发小记
    在WINPE中添加驱动
    DOS命令活用
    METRO开发中的多语言处理
  • 原文地址:https://www.cnblogs.com/dotnetmvc/p/3663388.html
Copyright © 2020-2023  润新知