Asp.net mvc 只将用户存储在会话中而不使用表单身份验证是否有害

Asp.net mvc 只将用户存储在会话中而不使用表单身份验证是否有害,asp.net-mvc,authentication,forms-authentication,Asp.net Mvc,Authentication,Forms Authentication,在过去的项目中,我一直使用表单身份验证。 现在在这个项目中,构建了一个自定义身份验证实现 这很简单:当您登录时(使用登录表单,并根据数据库对凭据进行了肯定测试),您的用户ID存储在会话中 然后,在自定义的AuthorizationAttribute:AuthorizationAttribute中,检查会话中是否有用户ID。如果有:您已通过身份验证(允许访问该页面),如果没有:您将重定向到登录页面 我的直觉告诉我这听起来很简单,但老实说,我找不到一个理由证明表单身份验证比这个实现更好 你知道有什么

在过去的项目中,我一直使用
表单身份验证。

现在在这个项目中,构建了一个自定义身份验证实现

这很简单:当您登录时(使用登录表单,并根据数据库对凭据进行了肯定测试),您的
用户ID
存储在会话中

然后,在自定义的
AuthorizationAttribute:AuthorizationAttribute
中,检查会话中是否有用户ID。如果有:您已通过身份验证(允许访问该页面),如果没有:您将重定向到登录页面

我的直觉告诉我这听起来很简单,但老实说,我找不到一个理由证明表单身份验证比这个实现更好


你知道有什么原因吗?

从功能上讲,其实差别不大。使用Forms Auth,将加密值(票据)作为cookie发送到客户端。在每个后续请求中,客户机将cookie发送回服务器,Forms Auth解密票据并尝试查找匹配的用户。如果成功,客户端将被视为“登录”,而如果失败,客户端将被发送到登录页面以重新验证

在您的情况下,您可以在会话中设置用户id,该会话将表示会话id的加密值作为cookie发送给客户端。在每个后续请求中,客户机都会将cookie发送回服务器,在服务器上查找和恢复会话。如果会话成功恢复,则将显示用户id,并且客户端将被视为“已登录”。如果会话无法恢复,则没有用户id,客户端将被发送到登录页面以重新验证

Forms Auth独立于会话工作,因此您可以选择不在应用程序中使用会话,但仍使用Forms Auth。但是,它所做的一切都可以通过会话轻松处理

一个很大的区别在于攻击向量。在您的解决方案中,如果恶意实体访问了您的数据库或能够使用SQL注入,他们可以很容易地创建一个会话,使自己看起来“已登录”。限制这一点的一个好步骤是,不仅要检查用户id,还要检查用户id是否确实解析为有效用户。然而,即使这样,有效用户的id也可能很容易被随机猜测,特别是如果您使用的是自动递增主键

另一方面,如果使用Forms Auth,则无法向服务器提供有效的加密值,该值表示没有访问服务器的机器密钥的用户。这是一个更具挑战性的攻击向量,需要服务器的实际渗透。
尽管如此,最大的区别在于你的解决方案把你带到了这里,询问它到底有多好。微软的安全专家在其身份验证解决方案方面拥有数十年的经验。由于其产品的安装基数很大,恶意实体始终以其身份验证方案为目标,从而提供了强化。只有当有人推倒你的墙时,你才知道它有多好。在这之前,你只希望它能经受住攻击。但是,在它被击倒后,你可以了解它是如何被击倒的,然后可以建造一堵没有缺陷的新墙。这就是微软几十年来一直在做的事情:每次都用更少的缺陷建造新墙。您没有这种经验,您的解决方案也没有经过这样的测试。这意味着您的解决方案,您构建的任何解决方案,无论它是否查找用户id,对于Forms Auth和其他内置形式的身份验证,都将始终存在缺陷。这就是为什么经验丰富的开发人员普遍说不要实现您自己的身份验证,我也会加入其中:不要实现您自己的身份验证。

从功能上讲,实际上没有太大区别。使用Forms Auth,将加密值(票据)作为cookie发送到客户端。在每个后续请求中,客户机将cookie发送回服务器,Forms Auth解密票据并尝试查找匹配的用户。如果成功,客户端将被视为“登录”,而如果失败,客户端将被发送到登录页面以重新验证

在您的情况下,您可以在会话中设置用户id,该会话将表示会话id的加密值作为cookie发送给客户端。在每个后续请求中,客户机都会将cookie发送回服务器,在服务器上查找和恢复会话。如果会话成功恢复,则将显示用户id,并且客户端将被视为“已登录”。如果会话无法恢复,则没有用户id,客户端将被发送到登录页面以重新验证

Forms Auth独立于会话工作,因此您可以选择不在应用程序中使用会话,但仍使用Forms Auth。但是,它所做的一切都可以通过会话轻松处理

一个很大的区别在于攻击向量。在您的解决方案中,如果恶意实体访问了您的数据库或能够使用SQL注入,他们可以很容易地创建一个会话,使自己看起来“已登录”。限制这一点的一个好步骤是,不仅要检查用户id,还要检查用户id是否确实解析为有效用户。然而,即使这样,有效用户的id也可能很容易被随机猜测,特别是如果您使用的是自动递增主键

另一方面,如果使用Forms Auth,则无法向服务器提供有效的加密值,该值表示没有访问服务器的机器密钥的用户。这是一个更具挑战性的攻击向量,需要服务器的实际渗透。 尽管如此,最大的区别在于你的解决方案把你带到了这里,询问它到底有多好。微软