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方法都要求在一个安全上下文中被执行,这里所谓的安全上下文主要指的是当前请求者是一个经过授权的用户.授权的本质就是让用户在他许可的权限范围内做他能够做的事情,授权的前提是请求者 ...
随机推荐
- golang 中 string 转换 []byte 的一道笔试题
背景 去面试的时候遇到一道和 string 相关的题目,记录一下用到的知识点.题目如下: s:="123" ps:=&s b:=[]byte(s) pb:=&b s ...
- java基础常见面试题,这是一篇超长的随笔!!!
1. Java基础部分....................................................... 4 1.一个".java"源文件中是否可以包括 ...
- c#Socket服务器与客户端的开发(1)
上个项目中用到了Socket通讯,项目中直接借助SuperSocket实现,但是我觉得这毕竟是一个我没接触过的东西,所以也顺便学习了一下原生socket的使用,做了一个socket服务器与客户端的开发 ...
- CSS 圣杯布局 / 双飞翼布局的实现
工作的越久,有些基础知识我们可能就逐渐淡忘了,今天我们来回顾一下css的圣杯布局和双飞翼布局, 这两个名词你可能不熟, 那三栏布局你肯定就非常熟悉了, 就是两边定宽, 中间自适应 的 布局 1 , 圣 ...
- SpringBoot之旅第四篇-web开发
一.引言 有了自动配置,springboot使web开发变得简单,这个在springboot之旅中的第一篇中就有体现,实际的开发中当然不会这么简单,很多时候我们都需要自己去定制一些东西.web开发的东 ...
- Windows下安装tesserocr
很难受,由于这两天重装了系统,又得重新配置环境了,而我在安装tesserocr的时候踩了一些坑,于是想写出来分享一下. 一.安装tesseract 要安装tesserocr,首先要下载tesserac ...
- kubernetes实践之一:kubernetes二进制包安装
kubernetes二进制部署 1.环境规划 软件 版本 Linux操作系统 CentOS Linux release 7.6.1810 (Core) Kubernetes 1.9 Docker 18 ...
- DSAPI 提取中间文本(字符串)
提取中间文本(源文本 As String, 前导文本 As String, 结束文本 As String, Optional 移除文本 As String = "", Option ...
- HTML5将footer置于页面最底部的方法(CSS+JS)
JavaScript: <script type="text/javascript"> $(function(){ function footerPosition(){ ...
- SQL2005打SP4补丁报错:无法安装Windows Installer MSP文件解决方案
错误如图: 解决方案分享如下: 第一步:卸载下图红框圈住的玩艺. 第二步:把SP4补丁文件解压,找到下图红框圈住的玩艺: 第三步:重新运行SP4补丁安装文件,安装正常.