一、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>&copy; @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)的更多相关文章

  1. Nginx访问控制_登陆权限的控制(http_auth_basic_module)

    Nginx提供HTTP的Basic Auth功能,配置了Basic Auth之后,需要输入正确的用户名和密码之后才能正确的访问网站. 我们使用htpasswd来生成密码信息,首先要安装httpd-to ...

  2. Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级

    1.权限管理 权限管理的基本定义:百度百科. 基于<Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员.后台管理员同时登录>我们做过了登录认证, ...

  3. asp.net core根据用户权限控制页面元素的显示

    asp.net core根据用户权限控制页面元素的显示 Intro 在 web 应用中我们经常需要根据用户的不同允许用户访问不同的资源,显示不同的内容,之前做了一个 AccessControlHelp ...

  4. ASP.NET -- WebForm -- Cookie的使用 应用程序权限设计 权限设计文章汇总 asp.net后台管理系统-登陆模块-是否自动登陆 C# 读写文件摘要

    ASP.NET -- WebForm -- Cookie的使用 ASP.NET -- WebForm --  Cookie的使用 Cookie是存在浏览器内存或磁盘上. 1. Test3.aspx文件 ...

  5. wex5 教程 之 图文讲解 全局可观察变量与登陆状态全局控制

    一 先说说,这两个概念是什么意思 全局可观察变量?没听说过,只听过全局变量,那你out了,因为我要充分发挥绑定技术来控制页面部局,组件的隐藏与显示,文字内容,样式改变.看我博文大家知道,我想用绑定技术 ...

  6. 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的返回值自动进行各种序列化处理(序列化为 ...

  7. mysql的root的权限被控制无法授权

    一.环境: MariaDB [(none)]> select version(); +----------------+ | version()      | +---------------- ...

  8. 拍照权限,GPS权限的控制

    最近项目中会遇到一些手机用户权限的问题,从网上百度了一下,发现有一些方法不能解决判断用户权限的是否开关,下面我就介绍两种权限的判断 1 拍照的权限控制 public static boolean is ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB  升级后界面效果如下: 任务调度系统界面 http: ...

随机推荐

  1. Mac上使用jenkins+ant执行第一个程序

    本文旨在让同学们明白如何让jenkis在mac笔记本上运行,以模拟实际工作中在linux上搭建jenkins服务平台首先按照笔者的习惯先说一下如何安装jenkis和tomcat,先安装tomcat,在 ...

  2. 【Unity3D与23种设计模式】建造者模式(Builder)

    GoF中定义: "将一个复杂的构建流程与它的对象表现分离出来,让相同的构建流程可以产生不同的对象行为表现." 建造者模式可以分为两个步骤来实施: 1.将复杂的构建流程独立出来,并将 ...

  3. Win 及 Linux 查找mac地址的方法

    1. Windows系统中 - 调出cmd命令行 - 运行Getmac命令.命令行中输入: getmac /v /fo list 并按下回车键 - 查找物理地址.这是MAC地址的另一种描述方式.因为在 ...

  4. 理解C语言中几个常见修饰符

    写在前面 今天下午一个同事问「register」关键字是什么作用?噢,你说的是「register」啊,它的作用是……脑袋突然断片儿,我擦,啥意思来着,这么熟悉的陌生感.做C语言开发时间也不短了,不过好 ...

  5. spring Boot+spring Cloud实现微服务详细教程第二篇

    上一篇文章已经说明了一下,关于spring boot创建maven项目的简单步骤,相信很多熟悉Maven+Eclipse作为开发常用工具的朋友们都一目了然,这篇文章主要讲解一下,构建spring bo ...

  6. Maven-05:插件目标

    在学习插件和生命周期的绑定关系之前,必须先了解插件目标(plugin goal). 我们知道,Maven的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的构件形式存在,因此Mav ...

  7. 套接字API

    Q:套接字特点 A:管道,消息队列,信号量,共享内存这些通信机制只能允许同一计算机上运行的进程相互通信,而套接字不仅可以提供在同一计算机上的进程间通信,还可以提供不同计算机上的进程间通信. 服务器端: ...

  8. 对lua表中数据按一定格式处理,循环

    function putStartCard(handCard) function dataDeal(array,a,b,c) cclog("进入datadeal=============== ...

  9. PHP 引用是个坑,请慎用

    去年我参加了很多次会议,其中八次会议里我进行了相关发言,这其中我多次谈到了 PHP 的引用问题,因为很多人对它的理解有所偏差.在深入讨论这个问题之前,我们先回顾一下引用的基本概念,明确什么是" ...

  10. 一个非常标准的连接Mysql数据库的示例代码

    一.About Mysql 1.Mysql 优点 体积小.速度快.开放源码.免费 一般中小型网站的开发都选择 MySQL ,最流行的关系型数据库 LAMP / LNMP Linux作为操作系统 Apa ...