ASP.NET MVC5 Forms登陆+权限控制(控制到Action)
一、Forms认证流程
请先参考如下网址:
http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.html
本文主要介绍使用自定义的身份认证表示来实现认证
二、自定义的身份认证主要流程
主要代码如下:
1..登录验证完用户名和密码后写入Cookie信息
public static HttpCookie SingIn(string loginName,TUserData userData,int expiration)
{
if (string.IsNullOrEmpty(loginName))
throw new ArgumentNullException("loginName");
if (userData == null)
throw new ArgumentNullException("userData");
// 1. 把需要保存的用户数据转成一个字符串。
string data = null;
if (userData != null)
data = JsonConvert.SerializeObject(userData);
//(new JavaScriptSerializer()).Serialize(userData);
// 2. 创建一个FormsAuthenticationTicket,它包含登录名以及额外的用户数据。
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
, loginName, DateTime.Now, DateTime.Now.AddDays(), true, data);
// 3. 加密Ticket,变成一个加密的字符串。
string cookieValue = FormsAuthentication.Encrypt(ticket);
// 4. 根据加密结果创建登录Cookie
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue);
cookie.HttpOnly = true;
cookie.Secure = FormsAuthentication.RequireSSL;
cookie.Domain = FormsAuthentication.CookieDomain;
cookie.Path = FormsAuthentication.FormsCookiePath;
if (expiration > )
cookie.Expires = DateTime.Now.AddMinutes(expiration); HttpContext context = HttpContext.Current;
if (context == null)
throw new InvalidOperationException(); // 5. 写登录Cookie
context.Response.Cookies.Remove(cookie.Name);
context.Response.Cookies.Add(cookie);
return cookie;
}
2.在Global.asax 中解析Cookie携带的自定义信息
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
UserFormsPrincipal<UserInfo>.TrySetUserInfo(app.Context);
}
相关的解析方法
public static void TrySetUserInfo(HttpContext context)
{
if (context == null)
throw new ArgumentNullException("context");
// 1. 读登录Cookie
HttpCookie cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie == null || string.IsNullOrEmpty(cookie.Value))
return;
try
{
TUserData userData = null;
// 2. 解密Cookie值,获取FormsAuthenticationTicket对象
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket != null && string.IsNullOrEmpty(ticket.UserData) == false)
{
// 3. 还原用户数据
userData = JsonConvert.DeserializeObject<TUserData>(ticket.UserData);
}
if (ticket != null && userData != null)
{
// 4. 构造我们的UserFormsPrincipal实例,重新给context.User赋值。
context.User = new UserFormsPrincipal<TUserData>(ticket, userData);
}
}
catch { /* 有异常也不要抛出,防止攻击者试探。 */ }
}
3.自定义授权Attribute
public class RoleAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var isAuth = false;
if (!filterContext.RequestContext.HttpContext.Request.IsAuthenticated)
{
isAuth = false;
}
else
{
if (filterContext.RequestContext.HttpContext.User.Identity != null)
{
IList<Permission> pList = null;
var roleService = new UserServer("DefaultConnection");
var actionDescriptor = filterContext.ActionDescriptor;
var controllerDescriptor = actionDescriptor.ControllerDescriptor;
var controller = controllerDescriptor.ControllerName;
var action = actionDescriptor.ActionName;
var ticket = (filterContext.RequestContext.HttpContext.User.Identity as FormsIdentity).Ticket;
var userData = (filterContext.RequestContext.HttpContext.User as UserFormsPrincipal<UserInfo>).UserData;
string perListKey = string.Format("userPermission_{0}", userData.RoleId);
var cache = HttpRuntime.Cache.Get(perListKey) as List<Permission>;
if (cache != null)
{
pList = cache;
} if (pList != null)
{
isAuth = pList.Any(x => x.CName.ToLower() == controller.ToLower() && x.AName.ToLower() == action.ToLower());
}
}
}
if (!isAuth)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Home", action = "Index", returnUrl = filterContext.HttpContext.Request.Url, returnMessage = "您无权查看." }));
return;
}
else
{
base.OnAuthorization(filterContext);
}
}
}
4.Web.Config 在System.Web下新增配节
<authentication mode="Forms">
<forms name="LoginCookieName" loginUrl="~/Home/Index"></forms>
</authentication>
三、实现细粒度权限控制
1.构造BaseController 所有需要权限认证的Controller 都需要从此进行继承
public class BaseController : Controller
{
public BaseController()
{
var pList = new List<Permission>();
if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
var ticket = (System.Web.HttpContext.Current.User.Identity as FormsIdentity).Ticket;
var userData = (System.Web.HttpContext.Current.User as UserFormsPrincipal<UserInfo>).UserData;
string perListKey = string.Format("userPermission_{0}", userData.RoleId);
pList = HttpRuntime.Cache.Get(perListKey) as List<Permission>;
}
ViewBag.PerList = pList; }
}
2._Layout.cshtml中获取权限信息并对主菜单进行权限控制
@using FormAuth.Models;
@using FormAuth.Utils;
@{
var pList = ViewBag.PerList as List<Permission>;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - 我的 ASP.NET 应用程序</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("大思无疆", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
@if (pList != null)
{
if (pList.FirstOrDefault(m => m.CName.ToLower() == "hello") != null)
{
<li>@Html.ActionLink("你好", "Index", "Hello")</li>
}
if (pList.FirstOrDefault(m => m.CName.ToLower() == "world") != null)
{
<li>@Html.ActionLink("世界", "Index", "world")</li>
}
if (pList.FirstOrDefault(m => m.CName.ToLower() == "good") != null)
{
<li>@Html.ActionLink("棒棒哒", "Index", "good")</li>
}
} </ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - 我的 ASP.NET 应用程序</p>
</footer>
</div> @Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
3.对Action根据权限信息进行显示
@using FormAuth.Models;
@{
ViewBag.Title = "Index";
var perList = ViewBag.PerList as List<Permission>;
} <h2>Hello->Index</h2>
<div>
<ul >
@if (perList != null)
{
var helloList = perList.Where(m => m.CName.ToLower() == "hello");
foreach (var item in helloList)
{
@Html.ActionLink(item.ActCnName,item.AName)
}
}
</ul>
</div>
Action的权限已经在 2.3节已进行验证
项目github地址:https://github.com/GYY2046/FormAuth
注意事项:项目使用VS2017 数据库为Local DB 数据库的连接字符串为绝对路径注意修改!
如有错误欢迎指正。
ASP.NET MVC5 Forms登陆+权限控制(控制到Action)的更多相关文章
- Nginx访问控制_登陆权限的控制(http_auth_basic_module)
Nginx提供HTTP的Basic Auth功能,配置了Basic Auth之后,需要输入正确的用户名和密码之后才能正确的访问网站. 我们使用htpasswd来生成密码信息,首先要安装httpd-to ...
- Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级
1.权限管理 权限管理的基本定义:百度百科. 基于<Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员.后台管理员同时登录>我们做过了登录认证, ...
- asp.net core根据用户权限控制页面元素的显示
asp.net core根据用户权限控制页面元素的显示 Intro 在 web 应用中我们经常需要根据用户的不同允许用户访问不同的资源,显示不同的内容,之前做了一个 AccessControlHelp ...
- ASP.NET -- WebForm -- Cookie的使用 应用程序权限设计 权限设计文章汇总 asp.net后台管理系统-登陆模块-是否自动登陆 C# 读写文件摘要
ASP.NET -- WebForm -- Cookie的使用 ASP.NET -- WebForm -- Cookie的使用 Cookie是存在浏览器内存或磁盘上. 1. Test3.aspx文件 ...
- wex5 教程 之 图文讲解 全局可观察变量与登陆状态全局控制
一 先说说,这两个概念是什么意思 全局可观察变量?没听说过,只听过全局变量,那你out了,因为我要充分发挥绑定技术来控制页面部局,组件的隐藏与显示,文字内容,样式改变.看我博文大家知道,我想用绑定技术 ...
- ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml) 用javascript在客户端删除某一个cookie键值对 input点击链接另一个页面,各种操作。 C# 往线程里传参数的方法总结 TCP/IP 协议 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图 (转)值得学习百度开源70+项目
ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml) 我们都知道在使用WebApi的时候Controller会自动将Action的返回值自动进行各种序列化处理(序列化为 ...
- mysql的root的权限被控制无法授权
一.环境: MariaDB [(none)]> select version(); +----------------+ | version() | +---------------- ...
- 拍照权限,GPS权限的控制
最近项目中会遇到一些手机用户权限的问题,从网上百度了一下,发现有一些方法不能解决判断用户权限的是否开关,下面我就介绍两种权限的判断 1 拍照的权限控制 public static boolean is ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 任务调度系统界面 http: ...
随机推荐
- Lintcode223 Palindrome Linked List solution 题解
[题目描述] Implement a function to check if a linked list is a palindrome. 设计一种方式检查一个链表是否为回文链表. [题目链接] w ...
- 怎么用secureCRT连接Linux
首先要安装linux,参看:http://www.cnblogs.com/shenjieblog/p/5061282.html 然后要安装secureCRT,参看:http://www.cnblogs ...
- Pazera Free Audio Extractor 中文版 - 轻松将视频背景音乐/对话音频提取出来的免费软件
这个软件是用来提取视频中的音频的,方便快捷.但是有一个问题,就是如果我提取的视频的名字中有不支持的字符(比如泰文)的时候,那么这个就提取不出来.所以如果名字中有不支持的字符的时候就要先改一个名字,然后 ...
- 【Unity与23种设计模式】迭代器模式(Iterator)
GoF中定义: "在不知道集合内部细节的情况下,提供一个按序方法存取一个对象集合体的每一个单元." 迭代器模式由于经常使用到 已经被现代程序设计语言纳为标准语句或收录到标准函数库中 ...
- dhcp 的安装和配置文件
install: yum - y install dhcp modify : vim /etc/dhcp/dhcpd.conf ddns-update-style none;ignore cli ...
- spy++捕获窗口消息
打开spy++,窗口截图如下,点击窗口搜索按钮(红框标识) ,如果找不到对应的窗口,鼠标右键刷新即可. 鼠标左键点击窗口搜索图标,按住不放,拖到需要抓取消息的窗口上: spy++会自动在列表中高亮定位 ...
- IMLite轻量级即时通信工具开发指南
花了一周时间开发了一个简单的即时通信工具,勉强算是程序原型.现在我把开发流程和一些个人的想法记录下来.本文首先介绍程序架构和通信接口,之后会聚焦到服务器的信号槽设计原则,接下来将解释有关TCP通信的粘 ...
- Vue解析一之挂载全局变量与方法
1.在mian.js里面进行Vue对象的原型连的挂载Vue.prototype.$ajax = Ajax; 2.使用Mixin: VuVue.mixin({ data(){ return { Host ...
- 通过漫画轻松掌握HDFS工作原理
- 去除Vue在WebStorm中报命名空间的错误
Preferences -> Editor -> Inspections找到XML,把 Unbound XML namespace prefix的勾去掉