欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-04 09:42:23
上一篇博文中已经实现了如何在页面上使用自定义的属性即上篇博文所示的@this.U,今天将进一步研究用户自定义User Identity; 实现思路: 通过研究微软自带identity的套路,我们可以发现其实现此功能的接口为IIdentity、System.Security.Principal.IPr ......

上一篇博文中已经实现了如何在页面上使用自定义的属性即上篇博文所示的@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、创建验证类库项目

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

2、在nuget安装NewtonSoft.Json插件

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

 

 

3、创建用户信息基本类UserData,UTIdentity,UTPrincipal

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Auth
 8 {
 9     public class UserData
10     {
11         /// <summary>
12         /// 用户id
13         /// </summary>
14         public string UserId { get; set; }
15         /// <summary>
16         /// 昵称
17         /// </summary>
18         public string NickName { get; set; }
19 
20         /// <summary>
21         /// 登录名
22         /// </summary>
23         public string LoginName { get; set; }
24         /// <summary>
25         /// 角色id
26         /// </summary>
27         public string RoleId { get; set; }
28         /// <summary>
29         /// 角色名称
30         /// </summary>
31         public string RoleName { get; set; }
32     }
33 }
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Security.Principal;
  5 using System.Text;
  6 using System.Threading.Tasks;
  7 using System.Web;
  8 using System.Web.Security;
  9 
 10 namespace Auth
 11 {
 12     public class UTIdentity: IIdentity
 13     {
 14         /// <summary>
 15         /// forms 身份验证票据
 16         /// </summary>
 17         private FormsAuthenticationTicket ticket;
 18         /// <summary>
 19         /// http请求连接
 20         /// </summary>
 21         private HttpContext context = HttpContext.Current;
 22         /// <summary>
 23         /// 用户基本信息
 24         /// </summary>
 25         private UserData _userData;
 26         #region Property
 27         /// <summary>
 28         /// 认证方式
 29         /// </summary>
 30         public string AuthenticationType
 31         {
 32             get { return "Forms"; }
 33         }
 34         /// <summary>
 35         /// 名称(登录名)
 36         /// </summary>
 37         public string Name
 38         {
 39             get { return _userData.LoginName; }
 40         }
 41         /// <summary>
 42         /// 登录名称
 43         /// </summary>
 44         public string loginname
 45         {
 46             get { return _userData.LoginName; }
 47         }
 48         /// <summary>
 49         /// 通过验证
 50         /// </summary>
 51         public bool IsAuthenticated
 52         {
 53             get { return true; }
 54         }
 55         /// <summary>
 56         /// 用户Cookie数据
 57         /// </summary>
 58         public UserData UserData
 59         {
 60             get { return _userData; }
 61         }
 62         /// <summary>
 63         /// 用户ID
 64         /// </summary>
 65         public string UserId
 66         {
 67             get { return _userData.UserId; }
 68         }
 69         private string mIP = "";
 70         /// <summary>
 71         /// 用户IP
 72         /// </summary>
 73         public string IP
 74         {
 75             get
 76             {
 77                 if (string.IsNullOrEmpty(context.Request.UserHostAddress))
 78                 {
 79                     try
 80                     {
 81                         mIP = context.Request.UserHostAddress;
 82                     }
 83                     catch { }
 84                 }
 85                 return mIP;
 86             }
 87         }
 88         /// <summary>
 89         /// 是否是管理员
 90         /// </summary>
 91         public bool IsAdmin
 92         {
 93             get { return 1 > 0; }
 94         }
 95         /// <summary>
 96         /// 用户姓名
 97         /// </summary>
 98         public string UserName { get; private set; }
 99         /// <summary>
100         /// 部门
101         /// </summary>
102         public string RoleName { get; private set; }
103         #endregion
104 
105         public UTIdentity(FormsAuthenticationTicket ticket)
106         {
107             _userData = (UserData)Newtonsoft.Json.JsonConvert.DeserializeObject(ticket.UserData, typeof(UserData));
108             this.ticket = ticket;
109             this.RoleName = _userData.RoleName;
110             this.UserName = _userData.LoginName;
111         }
112     }
113 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Web.Security;
 7 
 8 namespace Auth
 9 {
10     public  class UTPrincipal: System.Security.Principal.IPrincipal
11     {
12         /// <summary>
13         /// 构造函数
14         /// </summary>
15         /// <param name="ticket"></param>
16         public UTPrincipal(FormsAuthenticationTicket ticket)
17         {
18             Identity = new UTIdentity(ticket);
19         }
20         /// <summary>
21         /// 身份信息
22         /// </summary>
23         public UTIdentity Identity
24         {
25             get;
26             private set;
27         }
28         /// <summary>
29         /// 返回身份信息
30         /// </summary>
31         System.Security.Principal.IIdentity System.Security.Principal.IPrincipal.Identity
32         {
33             get { return Identity; }
34         }
35 
36         public bool IsInRole(string role)
37         {
38             throw new NotImplementedException();
39         }
40     }
41 }

4、创建cookie读写操作工具类 CookieUtils

  1 using Newtonsoft.Json;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Linq;
  5 using System.Text;
  6 using System.Threading.Tasks;
  7 using System.Web;
  8 using System.Web.Security;
  9 
 10 namespace Auth
 11 {
 12     public class CookieUtils
 13     {
 14         public static string SYSTEMLOGINCOOKIEKEY = "SYSTEMLOGINCOOKIEKEY";
 15         /// <summary>
 16         /// 取得Cookie登录信息
 17         /// </summary>
 18         public static UserData GetLoginCookieInfo()
 19         {
 20             UserData ret = null; ;
 21             var cookie = HttpContext.Current.Request.Cookies[SYSTEMLOGINCOOKIEKEY];
 22             if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
 23             {
 24                 try
 25                 {
 26                     var ticket = FormsAuthentication.Decrypt(cookie.Value);
 27                     ret = (UserData)JsonConvert.DeserializeObject(ticket != null ? ticket.UserData : "", typeof(UserData));
 28                 }
 29                 catch
 30                 {
 31 
 32                 }
 33             }
 34             return ret;
 35         }
 36 
 37         public static void SaveLoginCookieInfo(UserData userData)
 38         {
 39             var json = JsonConvert.SerializeObject(userData, Formatting.None,
 40                       new JsonSerializerSettings()
 41                       {
 42                           ReferenceLoopHandling = ReferenceLoopHandling.Ignore
 43                       });
 44 
 45             FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userData.LoginName, DateTime.Now, DateTime.Now.AddMinutes(60), false, json);
 46             //数据加密
 47             string enyTicket = FormsAuthentication.Encrypt(ticket);
 48             HttpCookie cookie = new HttpCookie(SYSTEMLOGINCOOKIEKEY, enyTicket);
 49             HttpContext.Current.Response.Cookies.Add(cookie);
 50         }
 51 
 52         public static void RemoveAuthCookie(UTPrincipal principal)
 53         {
 54             HttpCookie removeCookie;
 55             string cookieName;
 56             int limit = HttpContext.Current.Request.Cookies.Count;
 57             for (int i = 0; i < limit; i++)
 58             {
 59                 cookieName = HttpContext.Current.Request.Cookies[i].Name;
 60                 if (cookieName == SYSTEMLOGINCOOKIEKEY) continue;
 61                 if (!cookieName.Equals(FormsAuthentication.FormsCookieName, StringComparison.OrdinalIgnoreCase))
 62                 {
 63                     continue;
 64                 }
 65                 removeCookie = new HttpCookie(cookieName);
 66                 removeCookie.Expires = DateTime.Now.AddDays(-1);
 67                 HttpContext.Current.Response.Cookies.Add(removeCookie);
 68             }
 69             if (principal != null)
 70             {
 71                 // FuncCodeMapStore.Remove(principal.Identity.userid);
 72             }
 73             HttpContext.Current.Session.Abandon();
 74         }
 75 
 76         /// <summary>
 77         /// 设置Cookie
 78         /// </summary>
 79         /// <param name="loginname">用户名</param>
 80         /// <param name="userData">用户数据</param>
 81         /// <param name="rememberMe">记住</param>
 82         public static HttpCookie SetAuthCookie(string loginname, UserData userData, bool rememberMe)
 83         {
 84             if (userData == null)
 85             {
 86                 throw new ArgumentNullException("userData");
 87             }
 88             string _userdata = JsonConvert.SerializeObject(userData, Formatting.None,
 89                         new JsonSerializerSettings()
 90                         {
 91                             ReferenceLoopHandling = ReferenceLoopHandling.Ignore
 92                         });
 93 
 94             //创建ticket
 95             var ticket = new FormsAuthenticationTicket(
 96                 1, loginname, DateTime.Now, DateTime.Now.AddDays(1), rememberMe, _userdata);
 97 
 98             //加密ticket
 99             var cookieValue = FormsAuthentication.Encrypt(ticket);
100 
101             //创建Cookie
102             var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
103             {
104                 HttpOnly = true,
105                 Domain = FormsAuthentication.CookieDomain,
106                 Path = FormsAuthentication.FormsCookiePath
107             };
108             if (rememberMe)
109                 cookie.Expires = DateTime.Now.AddDays(1);
110 
111             //写入Cookie
112             HttpContext.Current.Response.Cookies.Remove(cookie.Name);
113             HttpContext.Current.Response.Cookies.Add(cookie);
114 
115             //  Medicom.Common.Log.Info(loginname + " 登录");
116             var user = HttpContext.Current.User;
117             return cookie;
118         }
119 
120         /// <summary>
121         /// 解析身份认证信息
122         /// </summary>
123         /// <param name="request">http请求对象</param>
124         /// <returns>身份认证信息</returns>
125         public static UTPrincipal TryParsePrincipal(HttpRequest request)
126         {
127             if (request == null)
128                 throw new ArgumentNullException("request");
129 
130             try
131             {
132                 var cookie = request.Cookies[FormsAuthentication.FormsCookieName];
133                 if (cookie == null)
134                 {
135                     return null;
136                 }
137 
138                 var ticket = FormsAuthentication.Decrypt(cookie.Value);
139                 if (ticket != null)
140                 {
141                     UTPrincipal myPrincipal = new UTPrincipal(ticket);
142                     return new UTPrincipal(ticket);
143                 }
144             }
145             catch (Exception e)
146             {
147                 // Medicom.Common.Log.Error("解析登录信息错误:", e);
148             }
149             return null;
150         }
151     }
152 }

5、设置application.Web 配置文件web.config(非视图配置文件)表单验证。

 1  <system.web>
 2     <authentication mode="None" />
 3     <compilation debug="true" targetFramework="4.5.2" />
 4     <httpRuntime targetFramework="4.5.2" />
 5     <httpModules>
 6       <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
 7     </httpModules>
 8   </system.web>
 9   <system.webServer>
10     <modules>
11       <remove name="FormsAuthentication" />
12       <remove name="ApplicationInsightsWebTracking" />
13       <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
14     </modules>
15     <validation validateIntegratedModeConfiguration="false" />
16   </system.webServer>

6.在WebViewPage 定义用户信息实体类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 
 7 namespace Application.Web.Mvc
 8 {
 9     [ValidateInput(false)]
10     public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
11     {
12         public string U = "1111";
13         public new Auth.UTPrincipal User
14         {
15             get
16             {
17                 if (base.User == null)
18                 {
19                     return null;
20                 }
21                 if (base.User.GetType() != typeof(Auth.UTPrincipal))
22                 {
23                     return null;
24                 }
25                 return (Auth.UTPrincipal)base.User;
26             }
27         }
28     }
29     [ValidateInput(false)]
30     public abstract class WebViewPage : System.Web.Mvc.WebViewPage<dynamic>
31     {
32 
33     }
34 }

7、创建BaseController控制器,项目其他控制器均继承于此控制器类(此处定义user属性,便于自定义所存储的用户信息可在后台控制器层使用)

 1 using Auth;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Mvc;
 7 
 8 namespace Application.Web.Controllers
 9 {
10     public class BaseController : Controller
11     {
12         /// <summary>
13         /// 当前用户信息
14         /// </summary>
15         protected new UTPrincipal User
16         {
17             get
18             {
19                 if (base.User != null && base.User.GetType() == typeof(UTPrincipal))
20                 {
21                     return (UTPrincipal)base.User;
22                 }
23                 return null;
24             }
25         }
26     }
27 }

8、使用表单验证保存用户信息

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

 1  public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
 2         {
 3             if (!ModelState.IsValid)
 4             {
 5                 return View(model);
 6             } 
 7             var userData = new UserData()
 8             {
 9                 LoginName = model.Email,
10                 RoleName = "测试管理员",
11                 UserId = "1",
12                 NickName = "测试昵称",
13             };
14             CookieUtils.SaveLoginCookieInfo(userData);
15             CookieUtils.RemoveAuthCookie(this.User);
16             CookieUtils.SetAuthCookie(model.Email, userData, model.RememberMe);
17 
18             if (string.IsNullOrEmpty(returnUrl))
19             {
20                 return RedirectToAction("Index", "Home");
21             }
22 
23             else
24             {
25                 return Redirect(returnUrl);
26             }
27         }

9、在每次请求时在控制器层初始化用户基本信息并且赋值。便于控制器层能获取到自定义用户信息

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

  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用户身份识别系统(2)

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

 

 此博文为原创,转载请注明出处!!!!!