在过去的项目中,我一直与Forms authentication.
现在,在这个项目中,构建了一个自定义身份验证实现。
这非常简单:当您登录时(使用登录表单,并且凭据对数据库进行了正面测试),您的userid
将存储在会话中。
然后,在自定义AuthorizationAttribute : AuthorizeAttribute
中,检查是否在会话中有用户ID。如果有:您已通过身份验证(允许访问该页面),如果没有:您将被重定向到登录页面。
我的直觉说这听起来很简单,但要说得好,我找不到理由表单身份验证比这个实现更好。
你知道任何理由吗?
答案 0 :(得分:4)
从功能上讲,实际上并没有多大区别。使用Forms Auth,加密值(票证)将作为cookie发送到客户端。在每个后续请求中,客户端将cookie发送回服务器,Forms Auth对票证进行解密并尝试查找匹配的用户。如果成功,则将客户端视为“已登录”,如果失败,则将客户端发送到登录页面以重新进行身份验证。
在您的情况下,您在会话中设置用户ID,该会话将表示会话ID的加密值作为cookie发送给客户端。在每个后续请求中,客户端将cookie发送回服务器,在该服务器中查找并恢复会话。如果会话成功还原,则将显示用户标识,并将客户端视为“已登录”。如果无法恢复会话,则没有用户ID,客户端将被发送到登录页面以重新进行身份验证。
Forms Auth独立于Session工作,因此您可以选择不在应用程序中使用会话,但仍使用Forms Auth。但是,它所做的一切都可以通过Session轻松处理。
一个很大的区别就是攻击媒介。使用您的解决方案,如果恶意实体获得了对您数据库的访问权限或能够使用SQL注入,他们可以更轻松地创建一个会使其显示为“已登录”的会话。限制此操作的一个很好的步骤是不仅要检查用户ID,还要检查用户ID是否实际解析为有效用户。但是,即使这样,有效用户的id也可能很容易被随机猜测,特别是如果你使用自动递增的主键。
另一方面,使用Forms Auth,无法向代表用户的服务器提供有效的加密值,而无法访问服务器的机器密钥。这是一个更具挑战性的攻击媒介,需要实际渗透服务器。
所有这一切,最大的区别是你的解决方案带你到这里,问它实际上有多好。 Microsoft拥有数十年从事身份验证解决方案工作的安全专家。由于其产品的安装基础较大,恶意实体始终以其身份验证方案为目标,从而提供强化功能。你只知道如果有人把它击倒,你的墙有多好。在此之前,你只希望它能够抵御攻击。但是,在它被击倒后,你会了解如何它被击倒,然后可以建立一个没有那个缺陷的新墙。这就是微软几十年来一直在做的事情:每次都要建立缺陷少的新墙。您没有这种经验,并且您的解决方案尚未以这种方式进行测试。这意味着您的解决方案,您构建的任何解决方案,无论是否查找用户ID,都将始终缺乏Forms Auth和其他内置身份验证形式。这就是为什么经验丰富的开发人员普遍认为没有实现自己的身份验证,我将加入合唱:不要实现自己的身份验证。
答案 1 :(得分:3)
您永远不应该使用会话进行身份验证或任何安全性。
正如我在对克里斯的评论中提到的那样,
默认情况下,会话不使用加密的cookie。这意味着会话ID以纯文本形式发送。这很容易嗅探,任何人都可以获取该ID,并在非ssl连接上模拟其他用户。
即使你使用加密的会话cookie,会话也是" volatile"而auth票不是。 IIS会在它感觉到的时候终止会话,即使是在网站上做某事的过程中,IIS也可以杀死你的会话,现在你将无缘无故地登出。 IIS在需要清理内存时,当工作进程被回收时,异常被抛出和未被捕获时,以及几乎每当IIS决定它时都会终止会话。你不想要用户"登录"状态取决于IIS的突发奇想。
这甚至不会引起服务器群的问题......这是最好避免的......是的,您可以在服务器场中共享会话状态,但最好避免这样做,因为它& #39;巨大的性能瓶颈。
最后......为什么? IIS有一个完整的,骨简单的方法来做内置的auth。只需调用一次FormsAuthentication.SetAuthCookie和IIS就可以为您提供所有安全性......您已经使用了授权属性,那么为什么要创建自定义属性呢?这甚至没有任何意义。
就像有人说'#34;我知道Locks是一种备受尊重且经过良好测试的安全门的方式,但我更喜欢使用我的自定义面条方法"。