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:

Collapse | Copy Code
[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.

Collapse | Copy Code
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

最新文章

  1. java中的锁
  2. angularjs和ajax的结合使用 (二)
  3. EF架构~二级域名中共享Session
  4. Android之获取string.xml文件里面的方法
  5. 传递引用类型参数的两种方式(转自 MSDN)
  6. IOS设计模式第一篇之MVC
  7. mac上使用生成RSA公钥和密钥
  8. webexam项目杂记2
  9. 【Mood-17】 github中在本地进行上传的时候出现ERROR: Repository not found. fatal: The remote end hung up unexpectedly
  10. JavaScript中的作用域与函数和变量声明的提升
  11. yii console.php 报错 Property &quot;CConsoleApplication.theme&quot; is not defined.
  12. 数据结构(C语言版)顺序栈相关算法的代码实现
  13. [APIO2016]划艇
  14. Java反射之调用内部类
  15. 【js】js声明与数据类型
  16. 用于Spring Boot Jar部署的shell脚本
  17. C# Clone控件
  18. 统计numpy数组中每个值的个数
  19. 就这么简单!构建强大的WebShell防护体系
  20. FATAL bad indentation of a mapping entry at line 83, column 3: branch: master 已解决;

热门文章

  1. 《OD大数据实战》Flume入门实例
  2. 导出到Excel并且取消默认的科学计算法
  3. eclipse有生成不带参数的构造方法的快捷键吗
  4. 使用Aspose.Cells组件生成Excel文件
  5. [原创] - C#编程大幅提高OUTLOOK的邮件搜索能力!
  6. impersonate a user
  7. 编译busybox错误
  8. 【转】WCF和ASP.NET Web API在应用上的选择
  9. python numpy sum函数用法
  10. ubuntu下 apt-get install 下载的文件存放的目录