上一篇博文中已经实现了如何在页面上使用自定义的属性即上篇博文所示的@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)的更多相关文章

  1. ASP.Net Mvc实现自定义User Identity用户身份识别系统(1)

    目的 当我们新建asp.net mvc 项目时,我们在使用下图所示的代码是否有以下思考: 1,在this.User.Identity.Name,为什么可以使用this便可以选中Name属性: 2,若项 ...

  2. [ASP.NET MVC] 使用CLK.AspNet.Identity提供依权限显示选单项目的功能

    [ASP.NET MVC] 使用CLK.AspNet.Identity提供依权限显示选单项目的功能 CLK.AspNet.Identity CLK.AspNet.Identity是一个基于ASP.NE ...

  3. [ASP.NET MVC] 使用CLK.AspNet.Identity提供以角色为基础的访问控制(RBAC)

    [ASP.NET MVC] 使用CLK.AspNet.Identity提供以角色为基础的访问控制(RBAC) 程序代码下载 程序代码下载:点此下载 前言 ASP.NET Identity是微软所贡献的 ...

  4. ASP.NET MVC中加载WebForms用户控件(.ascx)

    原文:ASP.NET MVC中加载WebForms用户控件(.ascx) 问题背景 博客园博客中的日历用的是ASP.NET WebForms的日历控件(System.Web.UI.WebControl ...

  5. 转:【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链

    [译]Asp.net MVC 利用自定义RouteHandler来防止图片盗链   你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你 ...

  6. 【转】Asp.net MVC 通过自定义ControllerFactory实现构造器注入(重写DefaultControllerFactory)

    [转]Asp.net MVC 通过自定义ControllerFactory实现构造器注入 一.重写ControllerFactory的GetControllerInstance ControllerF ...

  7. 如何在 ASP.NET 应用程序中实现模拟用户身份(在ASP.NET中以管理员身份运行网站)

    前言 在实际的项目开发中,我们可能会需要调用一些非托管程序,而有些非托管程序需要有更高的身份权限才能正确执行.本文介绍了如何让IIS承载的ASP.NET网站以特定的账户执行,比如Administrat ...

  8. ASP.NET Identity系列02,在ASP.NET MVC中增删改查用户

    本篇体验在ASP.NET MVC中使用ASP.NET Identity增删改查用户. 源码在这里:https://github.com/darrenji/UseIdentityCRUDUserInMV ...

  9. [ASP.NET MVC] 利用自定义的AuthenticationFilter实现Basic认证

    很多情况下目标Action方法都要求在一个安全上下文中被执行,这里所谓的安全上下文主要指的是当前请求者是一个经过授权的用户.授权的本质就是让用户在他许可的权限范围内做他能够做的事情,授权的前提是请求者 ...

随机推荐

  1. 深度学习之Batch Normalization

    在机器学习领域中,有一个重要的假设:独立同分布假设,也就是假设训练数据和测试数据是满足相同分布的,否则在训练集上学习到的模型在测试集上的表现会比较差.而在深层神经网络的训练中,当中间神经层的前一层参数 ...

  2. ArrayList的add(E e)方法与扩容

    ArrayList是Java开发中经常用到的集合类,它是List接口的实现类,具有很高的查询性能,但不是线程安全的.本文主要讲述了ArrayList的add(E e)方法及该方法中涉及到的容量扩容技术 ...

  3. 小程序 表单 获取 formId

    微信小程序使用模板消息需要使用支付prepay_id或表单提交formId, 要获得 formId 需要在 form 标签中声明属性    report-submit="true" ...

  4. Python-爬取校花网视频(单线程和多线程版本)

    一.参考文章 python爬虫爬取校花网视频,单线程爬取 爬虫----爬取校花网视频,包含多线程版本 上述两篇文章都是对校花网视频的爬取,由于时间相隔很久了,校花网上的一些视频已经不存在了,因此上述文 ...

  5. redis基本类型以及优点特性

    1.什么是redis? redis是一个基于内存的高性能key-value数据库 2.redis基本数据类型及应用场景  支持多种数据类型: string(字符串)   String数据结构是简单的k ...

  6. CentOS7中搭建cobbler自动装机服务

    一.实验环境 一台centos7 epel源网址 https://fedoraproject.org/wiki/EPEL?rd=Epel 使用nat模式 二.实验步骤 1.下载epel源后进行文件夹挂 ...

  7. Dynamics 365 CE在Pre Delete插件中应用Image

    微软动态CRM专家罗勇 ,回复327或者20190428可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 在插件中限制记录的删除是常见的场景,比如根据statuscode ...

  8. 在ArcMap中发布FeatureLayer(要素图层)

    FeatureLayer(要素图层)是ArcGIS Server发布的一种很重要的地图服务,发布后使用提供的url地址就可以在代码中调用并在地图上显示.编辑这个FeatureLayer.在HTML页面 ...

  9. SQL Server关于predicate、density、selectivity、cardinality名词浅析

      在SQL Server中,我们要看懂执行计划和统计信息,我们可能需要深刻理解一些关键词,例如密度(Density).选择性(Selectivity).谓词(predicate).基数(Cardin ...

  10. lunix脚本进程挂掉时显示cpu和内存信息及挂掉的时间

    #!/bin/shwhile [ true ]; do #查询是否有8899正在运行的进程netstat -an|grep 8899if [ $? -ne 0 ]thennowtime=$(date ...