为什么使用FormsAuthenticationTicket与Windows身份验证?

kil*_*ack 6 cookies forms-authentication windows-authentication asp.net-mvc-4

我一直在网上阅读大量有关身份验证和授权的内容,最后确定了一些似乎正在运行的代码......但我并不完全理解它所做的一切(就FormsAuthenticationTicket而言).

我正在使用的MVC应用程序将处理一些敏感数据,我想要检查与验证和授权相关的所有操作.

我正在使用Windows身份验证;

<authentication mode="Windows" />
<authorization>    
  <deny users="?"/>
</authorization>
Run Code Online (Sandbox Code Playgroud)

我在SQL Server中有一组表,其中包含其他用户和权限信息.

  • 用户
  • 角色
  • UsersInRoles
  • 用于在应用程序和关联权限中定义对象的其他表.

在我的Global.asax中,我有以下方法的启发

http://www.codeproject.com/Articles/5182/Insight-into-Security-Model-using-Principal-and-Id

protected void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
  if (e.Identity == null || !e.Identity.IsAuthenticated)
  {
    //Redirect to error or access denied page
  }

  string userData = e.Identity.AuthenticationType;          

  var cachedUser = HttpContext.Current.Cache[e.Identity.Name] as User;

  if (cachedUser == null)
  {
    var user = repo.GetUserByFullUserName(e.Identity.Name);
    HttpContext.Current.Cache.Insert(e.Identity.Name, user, null, DateTime.Now.AddMinutes(2), Cache.NoSlidingExpiration);
    cachedUser = HttpContext.Current.Cache[e.Identity.Name] as User;
  }

  var userIdentity = e.Identity.Name;

  var formsAuthTicket = new FormsAuthenticationTicket(1, e.Identity.Name, DateTime.Now, DateTime.Now.AddMinutes(2), false, userData);

  var encryptedTicket = FormsAuthentication.Encrypt(formsAuthTicket);
  var httpcook = new HttpCookie("authCookie", encryptedTicket);
  Response.Cookies.Add(httpcook);
}



protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
  if (Request.IsAuthenticated)
  {
    var httpcook = Context.Request.Cookies["authCookie"];
    var formsAuthTicket = FormsAuthentication.Decrypt(httpcook.Value);

    var cachedUser = GetCachedUser(formsAuthTicket.Name);
    if (cachedUser == null)
      {
      cachedUser = CreateCachedUser(formsAuthTicket.Name);
      } 

    var genIdentity = new GenericCustomIdentity(cachedUser, Request.IsAuthenticated, formsAuthTicket.UserData);

    var genPrincipal = new GenericCustomPrincipal(genIdentity, cachedUser);

    HttpContext.Current.User = genPrincipal;
  }
}
Run Code Online (Sandbox Code Playgroud)

所以这是我的问题:

  1. 为什么在WindowsAuthentication_OnAuthenticate方法中有FormsAuthenticationTicket?我不能只在WinAuth方法中构建我的Identity和Principal对象吗?

  2. 在HttpContext.Current.Cache中存储用户数据存在安全隐患吗?由于这些方法被多次调用,我不希望每次请求都能访问db.有更好/更安全的替代方案吗?

  3. 我不熟悉使用FormsAuthenticationTickets,Identity和Principal,因此我们将非常感谢您提出任何意见或建议.对不起,这不是问题.

Eri*_*ips 3

为什么 WindowsAuthentication_OnAuthenticate 方法中有 FormsAuthenticationTicket?我不能在 WinAuth 方法中构建我的 Identity 和 Primary 对象吗?

Identity 和Principal 对象仅在客户端当前调用/请求期间存在。它们是HttpContext的一部分,并且由于缺乏更好的术语,在请求结束时被丢弃。一旦经过身份验证的人再次连接,就会创建一个新请求,并且默认情况下不会对他们进行身份验证。

FormsAuthenticationTicket (默认情况下)使用客户端的 cookie 来存储每个后续请求的身份验证信息这允许该Application_AuthenticateRequest方法使用 cookie 重新授权请求。

将用户数据存储在 HttpContext.Current.Cache 中是否存在安全风险?由于这些方法被多次调用,我不想每次请求都访问数据库。有更好/更安全的替代方案吗?

HttpContext.Cache存储在内存中如果服务器重置或应用程序池因任何原因重新启动,缓存就会消失。

是的,这是一个安全风险,您存储用户信息的是服务器内存。然而,风险非常小,除非有人拥有您的代码来查看您如何使用缓存,并且可以上传代码来读取缓存。

我不熟悉使用 FormsAuthenticationTickets、身份和委托人,因此任何意见或建议将不胜感激。抱歉,这不是一个问题。

链接到HttpContext.User (IPrincipal)及其属性 Identity 类型为IIdentity怎么样。这不是最具描述性的答案,但两个界面都非常基本。