我正在将一个ASP.NET应用程序移植到MVC,并且需要存储与认证用户相关的两个项目:角色列表和可见项目ID列表,以确定用户可以看到或看不到的内容。
我们过去曾将WSE与Web服务结合使用,这使得事情变得异常复杂,无法正常调试。现在,我们正在放弃我正在寻求的Web服务,以简单地简化解决方案,只是为了将这些东西存储在会话中。一位同事建议使用角色和成员资格提供者,但在研究这个问题时我发现了一些问题:
a)它遇到了与WSE类似但不同的问题,因为它必须以非常有限的方式使用,即使编写测试也很棘手;
b)RolesProvider唯一的缓存选项基于我们因安全原因而拒绝的Cookie;
c)它引入了并发症和额外不必要的行李;
简而言之,我们想要做的就是在用户会话中存储两个字符串变量或以安全的方式存储等价物,并在需要时引用它们。到目前为止,似乎是一个十分钟的工作需要花费几天时间进行调查,并且为了解决我们现在发现会话ID显然是伪造的问题,请参阅
http://blogs.sans.org/appsecstreetfighter/2009/06/14/session-attacks-and-aspnet-part-1/
我认为没有简单的方法来完成这项非常简单的工作,但我觉得无法相信。
任何人都可以:
a)提供有关如何使ASP.NET MVC会话安全的简单信息,因为我一直认为它们是安全的?
b)建议另一种简单的方法来为登录用户的角色等存储这两个字符串变量,而不必像上面所描述的那样用另一个替换一个复杂的噩梦?
谢谢。
答案 0 :(得分:7)
将用户的角色信息存储在服务器端会话中是安全的,因为会话无法被劫持。更广泛地重申这一点,如果经过身份验证的会话被劫持,则存储用户角色信息的位置并不重要。
我建议不要过多地相信你所链接的文章,但是从您的链接链接的2002年份报告是有意义的。以下是我的外卖:
不接受网址中嵌入的会话ID。
将时间集中在消除跨站点脚本编写危险,即扫描所有用户提供的数据并解析出可执行的java脚本。
发布完整域名的Cookie(例如myapp.mydomain.com)
在高级DNS运营商处托管您的域名,例如一个只允许从预设的远程IP地址进行DNS更改的文件。
请勿发布持久会话Cookie。
如果某人到达登录页面且会话ID已与经过身份验证的会话相关联,则重新发出会话Cookie。
更好的是,总是在成功验证时发出新的会话cookie并放弃之前的会话。 (这可以在IIS中配置吗?)
答案 1 :(得分:0)
进行安全连接的唯一方法是使用SSL。除此之外的任何东西,你只需要在“足够安全”时进行评估。
会话变量适用于存储值,但Web服务器可能会被循环使用,这会导致会话丢失。当发生这种情况时,您必须重新验证用户并再次设置会话变量。
会话变量本身是完全安全的,因为它永远不会离开服务器,除非您专门将其复制到响应中。
答案 2 :(得分:0)
您是否考虑过在MVC中设置自定义授权标记。我在另一个question中举了一个例子。
在初始授权(登录屏幕或会话开始)上,您也可以使用IP地址为会话值设定种子。然后在您的自定义授权中,您还可以验证IP仍然匹配。这将有助于确保某人不会“窃取”该人的会话。每次访问会话数据时,请确保传递请求者的IP并对其进行检查。
答案 3 :(得分:0)
您是否尝试在客户端级别控制对功能的访问?这是我公开角色和项目来控制客户端功能的唯一原因。
或者,您可以创建一个函数来获取允许用户角色使用的项目,然后即使在返回给Web应用程序的项目之外调用该函数,也可以阻止用户访问它们。
4Guys似乎展示了如何使用角色控制功能。
答案 4 :(得分:0)
我过去使用的方法是在SSL旁边使用cookie的对称加密。加密响应中的用户信息并在请求中解密。我并不认为这是万无一失或100%安全,我不想在银行应用程序中这样做,但它已经足够用于许多目的。
会话变量的主要问题是,如果将它们存储在内存中而不是将它们保存,那么您需要在Web场环境中将“粘性”会话应用于负载平衡。 Guffa是正确的,没有这个持久性会话,变量偶尔会丢失,导致用户体验不佳。
粘性会话可能导致负载均衡不均衡,可能会降低能够扩展的价值。
如果要保持会话以便Web场中的所有服务器都可以访问这些会话,那么最好使用Guid来识别用户,在cookie中对此进行加密并从中检索用户记录。每次你的数据存储。
答案 5 :(得分:0)
我显而易见的问题是,您为什么要在会话中存储用户角色?
以下是我对您的查询的回答,这有何帮助。我附上了一个小的演示应用程序供您查看并理解我的观点。在visual studio中打开此项目时,单击顶部的项目选项卡,然后选择asp.net配置。从显示的页面中,您可以执行用户管理。
您需要以某种安全的方式存储用户的角色吗?这个问题的答案是,当我们拥有asp.net成员资格,配置文件和角色框架来帮助我们解决这个问题时,您无需担心为任何用户存储角色。您需要做的就是在aspnet数据库中创建一个角色并将该角色分配给用户。
接下来,您希望以某种安全的方式存储两个字符串。我建议您使用用户配置文件存储用户特定信息。通过这种方式,您可以从profilecommon类中获得所需的信息。
末尾附带的演示应用程序答案 6 :(得分:0)
只是一个建议,您可以考虑使用这个小库:
http://www.codeproject.com/KB/aspnet/Univar.aspx
它具有cookie的服务器端实现,其中所有cookie都可以存储在服务器上,而asp.net认证用于识别用户。它支持加密,并且非常灵活,可以很容易地从一种存储类型切换到另一种存储类型。