开发与Web表单应用程序一致的自定义身份validation和授权系统

我正在创建一个新的ASP.NET MVC 4应用程序(实际上是我的第一个MVC应用程序),它是我以前的ASP.NET Web表单应用程序的一部分。 我从未在任何项目中使用ASP.NET内置身份validation方法。 这个新的MVC 4应用程序将在以前的应用程序的子域上发布。 登录将从之前的应用程序完成。 如果没有登录,应该从MVC应用程序提供返回URL以返回当前页面。但是,新用户注册,帐户恢复选项已经在以前的Web表单应用程序中开发,我不想在我的新MVC中复制它们应用。

如果成功登录,将从Web表单应用程序发出带有令牌编号的cookie token ,该令牌将共享给所有域,如*.maindomain.com

现在我想将自己的令牌validation方法与ASP.NET内置方法合并,以便我可以在新的MVC应用程序中使用Authorize和其他与安全相关的选项。

在我之前的应用程序中,我以下列方式开发了自定义用户validation系统。

首先,我有以下相关的SQL Server表

在此处输入图像描述

和以下课程

 public class Token { public static uint GenerateToken(string userEmail, string password, bool isPersistent) { // this static function generates a uint type unique token number // and put this in the cookie "token" using HttpContext.Current.Response object. // if isPersistent is set to true then cookie will be persistent otherwise not // if there is any problem in creating token then it will throw an Exception with proper message // Possible causes of not generating a token are // 1. Invalid useremail or password // 2. 'State' value in 'Member' table is 'EmailPending' or 'Suspended' (there is an enum for MemberState } public Token(uint tokenNo, bool validateImmediately = false) { // simply load token details with a few filed from member table from database // Call validate function if validateImmediately is set to true // Throws an exception if token does not exists in the database } public void Validate() { // Checks for everything like MemberState is Active and Token status is also Active and throws exception if anything wrong // and then check (LastAccessedOn.AddSeconds(TokenLife) < AppSettings.Now) is not true // Call UpdateStatus function with new token status and current page from HttpContext in comment parameter } public void UpdateStatus((TokenStatus newStatus, string comment = "") { // simply write both newStatus and Comment in Token table // and remove the token cookie if newStatus is not set to Active } public uint TokenNumber { get; private set; } public uint MemberNumber { get; private set; } // from Member table public string Name { get; private set; } // from Member table public MemberState MemberState { get; private set; } // from Member table public string MemberEmail { get; private set; } // from member table public uint BusinsessNo { get; private set; } // from Business table public DateTime CreatedOn { get; private set; } public DateTime LastAccessedOn { get; private set; } public uint TokenLife { get; private set; } // from member public string CreatedIP { get; private set; } public string LastIP { get; private set; } public bool IsPersistent { get; private set; } public TokenStatus Status { get; private set; } public string Comment { get; private set; } public static Token Current { get { if (_t == null) _t = new Token(uint.Parse(HttpContext.Current.Request.Cookies["token"].Value)); return _t; } } private static Token _t; } public class Member { // all member related operations like new member, send verification email and verify email } 

对于注销用户,我只需调用UpdateStatus (TokenSatus.Closed, "User logged out") 。 此方法将负责删除cookie。

注意:成员类有一个属性bool IsAdmin 。 你知道它的原因。

请根据我在MVC应用程序中的需求,建议我开发认证系统的最佳解决方案。 我再次告诉你, New UserAccount RecoveryEmail Verification将在我之前的ASP.NET Web表单应用程序中完成。 我需要将我的Token类的Validate()方法放在MVC应用程序的正确位置。 我真的很困惑互联网上的几种解决方案。

如果您手动滚动自己的身份validation,则安全性只能与安全地在客户端cookie中存储Ticket的方式一样强。

通常,您希望加密身份validation票证/令牌并通过SSL进行访问。 只要您在客户端安全地存储cookie,就不应该成为问题。

我还想建议看看ASP.Net如何创建表单身份validation票证。

注意:如果使用ASP.Net表单身份validation票证,则无需在数据库中存储票证/令牌,因为用户将在每个页面请求时将auth票证发送到服务器。

 var now = DateTime.UtcNow.ToLocalTime(); var ticket = new FormsAuthenticationTicket( 1, /*version*/ MemberID, now, now.Add(FormsAuthentication.Timeout), createPersistentCookie, TokenID, /*custom data*/ FormsAuthentication.FormsCookiePath); var encryptedTicket = FormsAuthentication.Encrypt(ticket); var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) { HttpOnly = true, Secure = FormsAuthentication.RequireSSL, Path = FormsAuthentication.FormsCookiePath }; if (ticket.IsPersistent) { cookie.Expires = ticket.Expiration; } if (FormsAuthentication.CookieDomain != null) { cookie.Domain = FormsAuthentication.CookieDomain; } _httpContext.Response.Cookies.Add(cookie); 

如何创建主体对象

一旦为经过身份validation的用户请求了一个页面,您需要从cookie中检索身份validation票证,并创建一个Principal对象。

 // In Global.asax.cs void Application_AuthenticateRequest(object sender, EventArgs e) { HttpCookie decryptedCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(decryptedCookie.Value); var identity = new GenericIdentity(ticket.Name); var principal = new GenericPrincipal(identity, null); HttpContext.Current.User = principal; Thread.CurrentPrincipal =HttpContext.Current.User; } // In action method, how to check whether user is logged in if (User.Identity.IsAuthenticated) { } 

我是否需要延长cookie过期时间?

如果将slidingExpiration保留为true(默认情况下为true),则会自动增加到期时间。 (阅读更多文章)

在高级简洁概述中,您可以执行以下操作:

如果你想继续你所拥有的,那么最好的解决方案是编写一个自定义HTTP模块来处理你的MVC Web应用程序的身份validation。 大多数身份validation模块(Windows,Forms等)都是通过HTTP模块完成的。 在这里,您可以读取请求和相应的cookie,并设置当前请求和线程的主体对象。 此外,如果发生HTTP 401 – 因为未经身份validation的用户正在请求您的mvc webapp的安全资源 – 您可以将它们重定向到其他Web应用程序的登录页面,并让他们将用户重定向回用户最初请求的用户。

你可能采取的另一条道路是重新评估你所拥有的。 您基本上是在尝试为应用程序实现单点登录联合身份/身份validation 。 为此我建议为此设计解决方案。 SAML和WS-Federation协议是提供此function的两种流行标准。 两种协议都实现了或多或少相同的目标。

有很多解决方案,基于这些协议的一个解决方案。

例如,一个是Windows Identity Foundation 。 从.Net 4.5开始,它集成在.Net框架中。 之前可以单独下载。 WIF支持WS-Federation协议。 这里的一切都基于他们所谓的基于声明的安全性(通过以下链接查看有关此主题的更多信息)。

尽管存在一些CTP版本的旧库,但WIF不支持SAML协议。 我不建议使用它。

继续重新评估您如何validation用户身份并管理其身份可能需要做很多工作。 因此,您可以自行决定是否值得投资。 我必须完成,但这里有一些指向手头主题的链接:

  • 联合身份
  • 索赔简介
  • 基于声明的身份
  • 基于声明的安全性介绍 – 第1部分和其他部分。
  • SSO与联合登录

虽然它不是一个随时可用的答案,但我希望它可以帮助您找到答案。 祝好运!