【问题标题】:Is it alright to put sensitive data into the cache? ASP MVC将敏感数据放入缓存可以吗? ASP MVC
【发布时间】:2015-12-04 19:46:39
【问题描述】:

我目前为我的 MVC 应用程序实现了一些“检查器”。

到目前为止,这是我所拥有的,

  1. 授权(表格)
  2. 身份验证(自定义 RoleProvider)
  3. 操作过滤器(以确保用户不会输入任何虚假的身份证号码或尝试通过编辑GET url 来访问其他人的数据。

我有几个关于 ASP MVC 上 cache 最佳实践的问题。

这是我的登录实现:

  [HttpGet]
    [ActionName("login")]
    public ActionResult login_load()
    {
        return View();
    }

    [HttpPost]
    [ActionName("login")]
    public ActionResult login_post(string uname,string pword)
    {

        using (EmployeeContext emp = new EmployeeContext())
        {
           //h student log = new student();
            int success = emp.login.Where(x => x.username == uname && x.password == pword).Count();
            if (success == 1)
            {
                int id = (from logs in emp.login
                          join rol in emp.roles on logs.role equals rol.id
                          where logs.username == uname
                          select logs.id).First();

                FormsAuthentication.SetAuthCookie(uname, false);
                HttpRuntime.Cache.Insert("id", id);
                return RedirectToAction("Details", "Enrollment", new { id = id});
            }
            return View();
        }
    }

(我计划尽快实施 H&S)

无论如何,到目前为止,这是我的担忧:

  1. 出于安全考虑,是否可以将id 之类的内容存储在缓存中?或者如果我使用sessions 会更好?
  2. 假设我成功登录,我添加了另一行代码:

    HttpRuntime.Cache.Insert("id", id);

    它是要编辑我以前的记录还是要添加另一个条目? 我从我的自定义RoleProviderHttpRuntime.Cache.Insert(cacheKey, roles, null, DateTime.Now.AddMinutes(_cacheTimeoutInMinute), Cache.NoSlidingExpiration); 中获得了这段代码,我相信每次我询问具有[Authorize(Role="users")] 保护的控制器时,它们都会被“解雇”。那么它是创建一个新条目还是编辑以前/现有的条目?

  3. 我是否应该担心在用户决定退出后立即删除/清除我的cache?我的角色提供者超时当前设置为20 minutes

我需要id,因为除了用户名之外,它是我的唯一标识符,我用它来比较用户尝试访问的任何 ID。

我正在考虑是否可以编辑缓存并将其用于我的应用程序。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-4 caching


    【解决方案1】:

    不必担心存储 ID,您需要返回并重构以使用 MVC 框中的内置身份信息。查看您的代码,我只能假设该系统将以纯文本形式存储密码。您不会通过任何此类系统的合规性。

    关于“这是否安全”的经验法则是不要自己编写。找到经过验证的产品并使用它。

    如果由于某种原因,MVC 提供的内置身份系统无法满足您的要求,请查看以下内容:https://github.com/brockallen/BrockAllen.MembershipReboot

    仅供参考: 身份系统是登录、注销和管理登录用户的服务。随意前往这里以了解有关 MVC 内置系统的更多信息:http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity

    【讨论】:

    • 是的,到目前为止它是纯文本,用于测试目的。我可能迟早会散列它。但好吧,我会检查出来。 Role Provider 和 FormAuthentication 还不够吗?
    • 请相信我,你迟早会放弃所有基于身份验证的东西。加密不是你可以涉足的领域,它需要多年的专业知识。当谈到加密货币时,我相当了解,我什至不会开玩笑说尝试推出自己的加密货币。请去学习一下 MVC 默认的做法,这意味着所有的代码都已经编写好了,并且在生产运行系统中得到了证明!
    • 好的,谢谢。是custom user principal and identity 吗?
    • 我快速浏览了您的个人资料,看起来您是一名 C++ 开发人员,混入了一些 C#。我强烈建议试用复数视力(或者只是购买一个潜艇,这太棒了)并学习以下课程:--C# 基础:pluralsight.com/courses/csharp-fundamentals-csharp5--使用 ASP.NET MVC4 构建应用程序pluralsight.com/courses/mvc4-building--ASP.NET MVC 5 基础:pluralsight.com/courses/aspdotnet-mvc5-fundamentals
    • 自定义用户主体和身份是什么意思?
    【解决方案2】:

    出于安全考虑,是否可以将 id 之类的内容存储在缓存中?或者如果我使用会话会更好?

    在这种情况下,它并没有太大的不同。但是,缓存不能分布在多个 Web 服务器上。会话状态可以通过更改web.config 文件的<sessionState> 部分。因此,您正在通过使用缓存在应用程序中构建可扩展性的固有限制。

    假设我成功登录,我添加了另一行代码:

    HttpRuntime.Cache.Insert("id", id);

    它是要编辑我以前的记录还是要添加另一个条目?我从我的自定义 RoleProvider HttpRuntime.Cache.Insert(cacheKey, roles, null, DateTime.Now.AddMinutes(_cacheTimeoutInMinute), Cache.NoSlidingExpiration);并且我相信每次我询问具有 [Authorize(Role="users")] 保护的控制器时,它们都会被“解雇”。那么它是创建一个新条目还是编辑以前/现有的条目?

    首先,您的代码存在重大缺陷。缓存旨在在站点上的所有用户之间共享。因此,当您插入一个值(例如 HttpRuntime.Cache.Insert("id", id);)时,所有用户都会看到它。如果您稍后使用此值查找数据,则用户数据将始终是最后一个登录用户的数据。

    您可以通过向键添加用户独有的值来解决此问题。

    var key = this.User.Identity.Name + "|Id";
    HttpRuntime.Cache.Insert(key, id);
    

    注意我在这里使用竖线字符作为分隔符。这是假设用户名不允许使用竖线字符(您还需要确保这一点)。

    其次,使用适当的缓存模式意味着您无需担心“id”是否存在,因为您已经进行了检查。使用缓存通常如下所示。

    public static string GetUserID()
    {
        // Check whether the user is logged in
        if (!HttpContext.Current.User.Identity.IsAuthenticated) {
            return 0;
        }
    
        // Make a UNIQUE key that can be used for this scenario
        var userName = HttpContext.Current.User.Identity.Name;
        var key = userName + "|Id";
    
        // Attempt to get the ID from the cache
        var id = HttpRuntime.Cache[key];
    
        // A null value indicates there was no value in the cache
        if (id == null)
        {
            // No ID in the cache, look it up from the database
            using (EmployeeContext emp = new EmployeeContext())
            {
                id = (from user in emp.login
                    where user.username = userName
                    select user.id).First();
            }
        
            // Store the ID from the database into the cache
            HttpRuntime.Cache.Insert(key, id, 
            
                // No Dependencies
                null, 
                
                // No absolute expiration (mimic the behavior of forms authentication)
                System.Web.Caching.Cache.NoAbsoluteExpiration, 
                
                // Timeout 20 minutes after the last access 
                // (to mimic the behavior of forms authentication)
                new TimeSpan(0, 20, 0),
    
                // Setting to NotRemovable ensures that if the
                // application pool restarts, you don't lose your cache
                System.Web.Caching.CacheItemPriority.NotRemovable, 
    
                // No callback needed here
                null);
        }
    
        return (string)id
    }
    

    当然,如果该值在登录时可用,则可以通过将其直接插入缓存来提高性能,但您需要确保在这种情况下使用相同的键。

    在这种情况下,Session 可能是更好的选择,但无论哪种方式,您都应该使用此模式在将值返回给用户之前仔细检查您是否有一个值。

    我是否应该担心在用户决定退出后立即删除/清除我的缓存?我的角色提供者超时当前设置为 20 分钟

    如果您使用会话状态而不是缓存,这会容易得多。用户注销时只需调用Session.Abandon()

    【讨论】:

    • 最后,我需要这样的答案。谢谢:D
    • 等等,我应该使用会话吗?无论如何var key = this.User.Identity.Name + "|Id"; 你能解释一下Identity 是什么吗?这是来自Identity framework 吗?
    • 不,这是表单身份验证的一部分。有通用接口IUserIIdentity,任何安全机制都可以实现它们来自定义用户配置文件数据的存储位置或添加特定于所使用的安全框架/方案的其他自定义行为。
    • 好的,非常感谢:D 不知道缓存是跨站点共享的。最后,如果我想实现类似的东西,sessionState 的正确网络配置是什么?我明天可以试试。
    • 会话的“正确”使用取决于您的应用程序。但最好使用 StateServer 或 SqlServer 将其存储在进程之外。见:msdn.microsoft.com/en-us/library/ms178586.aspx
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    • 2023-02-16
    • 2018-09-14
    • 1970-01-01
    • 2018-06-25
    • 2021-03-27
    相关资源
    最近更新 更多