一、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. WordPress用键盘左右方向键来查看上一篇和下一篇文章

    通过键盘来查看上下篇文章是不是很方便,这个其实就是条用键盘所对应的ASCII码来实现的,比如左右方向键所对应的ASCII码就是37和39,下面来看看实现怎么实现这个功能: 1.加载jQury库,当然很 ...

  2. 关于JDK和eclipse的安装和汉化

    参考网址:http://jingyan.baidu.com/article/f96699bb8b38e0894e3c1bef.html http://titanseason.iteye.com/blo ...

  3. java反射使用及性能比较

    环境准备 package com.lilei.pack09; public class Logger { public void show(){ System.out.println("he ...

  4. Python 中的继承、多态和封装

    涉及问题: Python 中如何实现多继承,会有什么问题? Python 中的多态与静态方法有什么区别? 答案要点如下: Python 中的继承,就是在定义类时,在括号中声明父类,简单示例如下: cl ...

  5. TensorFlow-谷歌深度学习库 体验一二三

    一个TensorFlow的运算可以看作是一个数据流图. 一个图呢则由一组操作和数据集组成. 操作(operation)代表运算单元 数据(tensor) 代表在各运算单元流动的数据单元 要想使用一个数 ...

  6. 1-1 struts2 基本配置 struts.xml配置文件详解

    详见http://www.cnblogs.com/dooor/p/5323716.html 一. struts2工作原理(网友总结,千遍一律) 1 客户端初始化一个指向Servlet容器(例如Tomc ...

  7. vue+webpack+element-ui+git

    webpack.config.jsconst { resolve } = require('path') const webpack = require('webpack') const HtmlWe ...

  8. echarts对每个data[i]的图片添加点击事件

    1.综述:以饼图为例,只需要对echarts对象option添加以下几行代码即可 //添加点击事件(单击),还有其他鼠标事件和键盘事件等等 myChart1.on("click", ...

  9. sys用户密码丢失找回密码的步骤和命令

    假设你的sys用户密码丢失,写出找回密码的步骤和命令? 1.确认哪个数据库实例的sys用户密码丢失:(例:数据库实例为orclA) 2.进入数据库实例的目录中找到PWDorclA.ora文件:(例目录 ...

  10. 关于JAVA开发工具IDEA使用

    安装IntelliJ IDEA 一.安装JDK 1 下载最新的jdk,这里下的是jdk-8u66 2 将jdk安装到默认的路径C:\Program Files\Java目录下 二.安装IntelliJ ...