ASP.Net Mvc实现自定义User Identity用户身份识别系统(2)
上一篇博文中已经实现了如何在页面上使用自定义的属性即上篇博文所示的@this.U,今天将进一步研究用户自定义User Identity;
实现思路:
通过研究微软自带identity的套路,我们可以发现其实现此功能的接口为IIdentity、System.Security.Principal.IPrincipal,(源码将会在后面展示),因此,第一步,我们需要创建继承IIdentity、System.Security.Principal.IPrincipal的实现类;UTIdentity.cs,UTPrincipal.cs;第二步,当我们定义好属于自己项目的身份识别的类之后,此时我们需要对我们定义的类初始化赋值,而初始化数据来源则应该从当前项目cookie中获取。第三步,根据第二步要求的数据来源要求,系统则需要保存用户登录信息到cookie之中。第四步:使用自定义用户身份识别系统。
总结:
整个程序则需要实现定义类继承相关接口>>>>>>实现登录保存Cookie信息>>>>>从cookie中获取登录信息,进行相应解密并将其对定义的类进行初始化>>>>>>使用自定义identity。下文将会贴出相应代码以及相应步骤的完善。
具体步骤:
基于上一篇博文的项目,我们将进行以下操作
1、创建验证类库项目
2、在nuget安装NewtonSoft.Json插件
3、创建用户信息基本类UserData,UTIdentity,UTPrincipal
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Auth
{
public class UserData
{
/// <summary>
/// 用户id
/// </summary>
public string UserId { get; set; }
/// <summary>
/// 昵称
/// </summary>
public string NickName { get; set; } /// <summary>
/// 登录名
/// </summary>
public string LoginName { get; set; }
/// <summary>
/// 角色id
/// </summary>
public string RoleId { get; set; }
/// <summary>
/// 角色名称
/// </summary>
public string RoleName { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security; namespace Auth
{
public class UTIdentity: IIdentity
{
/// <summary>
/// forms 身份验证票据
/// </summary>
private FormsAuthenticationTicket ticket;
/// <summary>
/// http请求连接
/// </summary>
private HttpContext context = HttpContext.Current;
/// <summary>
/// 用户基本信息
/// </summary>
private UserData _userData;
#region Property
/// <summary>
/// 认证方式
/// </summary>
public string AuthenticationType
{
get { return "Forms"; }
}
/// <summary>
/// 名称(登录名)
/// </summary>
public string Name
{
get { return _userData.LoginName; }
}
/// <summary>
/// 登录名称
/// </summary>
public string loginname
{
get { return _userData.LoginName; }
}
/// <summary>
/// 通过验证
/// </summary>
public bool IsAuthenticated
{
get { return true; }
}
/// <summary>
/// 用户Cookie数据
/// </summary>
public UserData UserData
{
get { return _userData; }
}
/// <summary>
/// 用户ID
/// </summary>
public string UserId
{
get { return _userData.UserId; }
}
private string mIP = "";
/// <summary>
/// 用户IP
/// </summary>
public string IP
{
get
{
if (string.IsNullOrEmpty(context.Request.UserHostAddress))
{
try
{
mIP = context.Request.UserHostAddress;
}
catch { }
}
return mIP;
}
}
/// <summary>
/// 是否是管理员
/// </summary>
public bool IsAdmin
{
get { return > ; }
}
/// <summary>
/// 用户姓名
/// </summary>
public string UserName { get; private set; }
/// <summary>
/// 部门
/// </summary>
public string RoleName { get; private set; }
#endregion public UTIdentity(FormsAuthenticationTicket ticket)
{
_userData = (UserData)Newtonsoft.Json.JsonConvert.DeserializeObject(ticket.UserData, typeof(UserData));
this.ticket = ticket;
this.RoleName = _userData.RoleName;
this.UserName = _userData.LoginName;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Security; namespace Auth
{
public class UTPrincipal: System.Security.Principal.IPrincipal
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="ticket"></param>
public UTPrincipal(FormsAuthenticationTicket ticket)
{
Identity = new UTIdentity(ticket);
}
/// <summary>
/// 身份信息
/// </summary>
public UTIdentity Identity
{
get;
private set;
}
/// <summary>
/// 返回身份信息
/// </summary>
System.Security.Principal.IIdentity System.Security.Principal.IPrincipal.Identity
{
get { return Identity; }
} public bool IsInRole(string role)
{
throw new NotImplementedException();
}
}
}
4、创建cookie读写操作工具类 CookieUtils
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security; namespace Auth
{
public class CookieUtils
{
public static string SYSTEMLOGINCOOKIEKEY = "SYSTEMLOGINCOOKIEKEY";
/// <summary>
/// 取得Cookie登录信息
/// </summary>
public static UserData GetLoginCookieInfo()
{
UserData ret = null; ;
var cookie = HttpContext.Current.Request.Cookies[SYSTEMLOGINCOOKIEKEY];
if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
{
try
{
var ticket = FormsAuthentication.Decrypt(cookie.Value);
ret = (UserData)JsonConvert.DeserializeObject(ticket != null ? ticket.UserData : "", typeof(UserData));
}
catch
{ }
}
return ret;
} public static void SaveLoginCookieInfo(UserData userData)
{
var json = JsonConvert.SerializeObject(userData, Formatting.None,
new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
}); FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(, userData.LoginName, DateTime.Now, DateTime.Now.AddMinutes(), false, json);
//数据加密
string enyTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(SYSTEMLOGINCOOKIEKEY, enyTicket);
HttpContext.Current.Response.Cookies.Add(cookie);
} public static void RemoveAuthCookie(UTPrincipal principal)
{
HttpCookie removeCookie;
string cookieName;
int limit = HttpContext.Current.Request.Cookies.Count;
for (int i = ; i < limit; i++)
{
cookieName = HttpContext.Current.Request.Cookies[i].Name;
if (cookieName == SYSTEMLOGINCOOKIEKEY) continue;
if (!cookieName.Equals(FormsAuthentication.FormsCookieName, StringComparison.OrdinalIgnoreCase))
{
continue;
}
removeCookie = new HttpCookie(cookieName);
removeCookie.Expires = DateTime.Now.AddDays(-);
HttpContext.Current.Response.Cookies.Add(removeCookie);
}
if (principal != null)
{
// FuncCodeMapStore.Remove(principal.Identity.userid);
}
HttpContext.Current.Session.Abandon();
} /// <summary>
/// 设置Cookie
/// </summary>
/// <param name="loginname">用户名</param>
/// <param name="userData">用户数据</param>
/// <param name="rememberMe">记住</param>
public static HttpCookie SetAuthCookie(string loginname, UserData userData, bool rememberMe)
{
if (userData == null)
{
throw new ArgumentNullException("userData");
}
string _userdata = JsonConvert.SerializeObject(userData, Formatting.None,
new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
}); //创建ticket
var ticket = new FormsAuthenticationTicket(
, loginname, DateTime.Now, DateTime.Now.AddDays(), rememberMe, _userdata); //加密ticket
var cookieValue = FormsAuthentication.Encrypt(ticket); //创建Cookie
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
{
HttpOnly = true,
Domain = FormsAuthentication.CookieDomain,
Path = FormsAuthentication.FormsCookiePath
};
if (rememberMe)
cookie.Expires = DateTime.Now.AddDays(); //写入Cookie
HttpContext.Current.Response.Cookies.Remove(cookie.Name);
HttpContext.Current.Response.Cookies.Add(cookie); // Medicom.Common.Log.Info(loginname + " 登录");
var user = HttpContext.Current.User;
return cookie;
} /// <summary>
/// 解析身份认证信息
/// </summary>
/// <param name="request">http请求对象</param>
/// <returns>身份认证信息</returns>
public static UTPrincipal TryParsePrincipal(HttpRequest request)
{
if (request == null)
throw new ArgumentNullException("request"); try
{
var cookie = request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie == null)
{
return null;
} var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket != null)
{
UTPrincipal myPrincipal = new UTPrincipal(ticket);
return new UTPrincipal(ticket);
}
}
catch (Exception e)
{
// Medicom.Common.Log.Error("解析登录信息错误:", e);
}
return null;
}
}
}
5、设置application.Web 配置文件web.config(非视图配置文件)表单验证。
<system.web>
<!--<authentication mode="None" />-->
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" name="SYSTEMLOGINCOOKIEKEY" />
</authentication>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
</httpModules>
</system.web>
<system.webServer>
<modules>
<!--<remove name="FormsAuthentication" />-->
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
6.在WebViewPage 定义用户信息实体类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace Application.Web.Mvc
{
[ValidateInput(false)]
public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
{
public string U = "";
public new Auth.UTPrincipal User
{
get
{
if (base.User == null)
{
return null;
}
if (base.User.GetType() != typeof(Auth.UTPrincipal))
{
return null;
}
return (Auth.UTPrincipal)base.User;
}
}
}
[ValidateInput(false)]
public abstract class WebViewPage : System.Web.Mvc.WebViewPage<dynamic>
{ }
}
7、创建BaseController控制器,项目其他控制器均继承于此控制器类(此处定义user属性,便于自定义所存储的用户信息可在后台控制器层使用)
using Auth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace Application.Web.Controllers
{
public class BaseController : Controller
{
/// <summary>
/// 当前用户信息
/// </summary>
protected new UTPrincipal User
{
get
{
if (base.User != null && base.User.GetType() == typeof(UTPrincipal))
{
return (UTPrincipal)base.User;
}
return null;
}
}
}
}
8、使用表单验证保存用户信息
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var userData = new UserData()
{
LoginName = model.Email,
RoleName = "测试管理员",
UserId = "",
NickName = "测试昵称",
};
CookieUtils.SaveLoginCookieInfo(userData);
CookieUtils.RemoveAuthCookie(this.User);
CookieUtils.SetAuthCookie(model.Email, userData, model.RememberMe); if (string.IsNullOrEmpty(returnUrl))
{
return RedirectToAction("Index", "Home");
} else
{
return Redirect(returnUrl);
}
}
9、在每次请求时在控制器层初始化用户基本信息并且赋值。便于控制器层能获取到自定义用户信息
protected void Application_PostAuthenticateRequest(object sender, System.EventArgs e)
{
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
var user = Auth.CookieUtils.TryParsePrincipal(HttpContext.Current.Request);
if (user != null)
{
HttpContext.Current.User = user;
}
}
测试:
控制器层获取值
界面获取值
此博文为原创,转载请注明出处!!!!!
ASP.Net Mvc实现自定义User Identity用户身份识别系统(2)的更多相关文章
- ASP.Net Mvc实现自定义User Identity用户身份识别系统(1)
目的 当我们新建asp.net mvc 项目时,我们在使用下图所示的代码是否有以下思考: 1,在this.User.Identity.Name,为什么可以使用this便可以选中Name属性: 2,若项 ...
- [ASP.NET MVC] 使用CLK.AspNet.Identity提供依权限显示选单项目的功能
[ASP.NET MVC] 使用CLK.AspNet.Identity提供依权限显示选单项目的功能 CLK.AspNet.Identity CLK.AspNet.Identity是一个基于ASP.NE ...
- [ASP.NET MVC] 使用CLK.AspNet.Identity提供以角色为基础的访问控制(RBAC)
[ASP.NET MVC] 使用CLK.AspNet.Identity提供以角色为基础的访问控制(RBAC) 程序代码下载 程序代码下载:点此下载 前言 ASP.NET Identity是微软所贡献的 ...
- ASP.NET MVC中加载WebForms用户控件(.ascx)
原文:ASP.NET MVC中加载WebForms用户控件(.ascx) 问题背景 博客园博客中的日历用的是ASP.NET WebForms的日历控件(System.Web.UI.WebControl ...
- 转:【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链
[译]Asp.net MVC 利用自定义RouteHandler来防止图片盗链 你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你 ...
- 【转】Asp.net MVC 通过自定义ControllerFactory实现构造器注入(重写DefaultControllerFactory)
[转]Asp.net MVC 通过自定义ControllerFactory实现构造器注入 一.重写ControllerFactory的GetControllerInstance ControllerF ...
- 如何在 ASP.NET 应用程序中实现模拟用户身份(在ASP.NET中以管理员身份运行网站)
前言 在实际的项目开发中,我们可能会需要调用一些非托管程序,而有些非托管程序需要有更高的身份权限才能正确执行.本文介绍了如何让IIS承载的ASP.NET网站以特定的账户执行,比如Administrat ...
- ASP.NET Identity系列02,在ASP.NET MVC中增删改查用户
本篇体验在ASP.NET MVC中使用ASP.NET Identity增删改查用户. 源码在这里:https://github.com/darrenji/UseIdentityCRUDUserInMV ...
- [ASP.NET MVC] 利用自定义的AuthenticationFilter实现Basic认证
很多情况下目标Action方法都要求在一个安全上下文中被执行,这里所谓的安全上下文主要指的是当前请求者是一个经过授权的用户.授权的本质就是让用户在他许可的权限范围内做他能够做的事情,授权的前提是请求者 ...
随机推荐
- SSRS报表服务随笔(rdl报表服务)-报表数据:使用第三方控件生成条形码
因为工作需要,需要将订单号显示成条形码,比如数据库存储的20190106A,我需要把这个转换为Code128来显示出来 在国内我没有找到这方面的教程,最后还是一个人自己摸索出来的 在这里我是使用的是B ...
- SSRS报表服务随笔(rdl报表服务)-报表参数
上一篇我们说了创建一个简单的显示报表,但在实际工作中,我们有很多要带条件的报表 现在先认识一下报表数据,首次打开SSDT,报表数据在窗口的左侧,要是找不到了,没关系,在工具栏-视图-最下面的报表数据 ...
- 100 天从 Python 新手到大师
Python应用领域和就业形势分析 简单的说,Python是一个“优雅”.“明确”.“简单”的编程语言. 学习曲线低,非专业人士也能上手 开源系统,拥有强大的生态圈 解释型语言,完美的平台可移植性 支 ...
- 基于async/non-blocking高性能redis组件库BeetleX.Redis
BeetleX.Redis是基于async/non-blocking模式实现的高性能redis组件库,组件支持redis基础指令集,并封装更简便的List,Hashset和Subscribe操作.除了 ...
- python——矩阵的奇异值分解,对图像进行SVD
矩阵SVD 奇异值分解(Singular Value Decomposition)是一种重要的矩阵分解方法,可以看做是对方阵在任意矩阵上的推广.Singular的意思是突出的,奇特的,非凡的,按照这样 ...
- 使用Keepalived构建LVS高可用集群
LVS的DR模型配置+Keepalive部署 介绍 下图为DR模型的通信过程,图中的IP不要被扑结构中的IP迷惑,图里只是为了说明DR的通信原理,应用到本例中的拓扑上其工作原理不变. 拓扑结构 服务器 ...
- 基于springboot搭建的web系统架构
从接触springboot开始,便深深的被它的简洁性深深的折服了,精简的配置,方便的集成,使我再也不想用传统的ssm框架来搭建项目,一大堆的配置文件,维护起来很不方便,集成的时候也要费力不少.从第一次 ...
- SQL Server内幕之数据页
数据页是包含已添加到数据库表中的用户数据的结构. 如前所述, 数据页有三种, 每个都以不同的格式存储数据. SQL server 有行内数据页.行溢出数据页和 LOB 数据页. 与 SQL serve ...
- 将一个html文件引入另一个html文件的div中
width="" height=""属性可根据要求自己设定
- 涨姿势:抛弃字母、数字和下划线写SHELL
PHP中异或 (^) 的概念 <?php echo"A"^"?";?> <?php echo"A"^"?&quo ...