简体   繁体   English

没有设计的OmniAuth:如何安全地实现“记住我”?

[英]OmniAuth without Devise: How can I securely implement Remember Me?

If I just store the provider and uid in a cookie is it secure enough? 如果我仅将provideruid存储在cookie中,是否足够安全? Or should I encrypt one or both of them? 还是我应该加密其中之一? Should I augment provider and uid with a secure token? 我应该使用安全令牌扩充provideruid吗?

Are there any other considerations that I should take into account? 还有其他我应该考虑的因素吗?

You can use a signed cookie . 您可以使用签名的cookie These are cryptographically signed making it impossible to alter their data without invalidating them. 这些都是经过加密签名的,因此无法在不使数据无效的情况下更改其数据。 This kind of cookie is typically used to store Rails session id/content. 这种cookie通常用于存储Rails会话ID /内容。

Keep in mind that these cookies can still be decoded (it's just base64), but it shouldn't be a problem as provider and uid don't need to be kept secret. 请记住,这些cookie仍可以被解码(只是base64),但这不应该成为问题,因为provideruid不需要保密。

If you don't want the cookie's content to be readable, you can use an encrypted cookie . 如果您不希望cookie的内容可读,则可以使用加密的cookie

You can read more about the different types of cookies proposed by Rails here in the ActionDispatch::Cookies documentation 您可以在ActionDispatch :: Cookies文档中阅读有关Rails建议的不同类型的Cookie的更多信息。

You say you can sign a user into your website when she visits if you've stored the provider and uid values you get from omniauth in a cookie. 您说如果用户将您从omniauth获得的provideruid值存储在cookie中,则可以在用户访问网站时对其进行登录。 The problem with this is that it's not reliable as a means of authentication . 这样做的问题是,它作为身份验证手段并不可靠。 Do you want to actually authenticate the user of your website? 您是否要实际验证您网站的用户? Then you need much more than just data that will allow you retrieve a unique user id from your database, as you recognize. 这样,您将需要的不仅仅是数据,这将使您能够从数据库中检索唯一的用户ID。 You need some sort of guarantee that the user id you're associating with the session represents the user you think it does. 您需要某种方式保证与会话关联的用户ID代表您认为的用户。

"Remember me" essentially relies on the assumption that the user-agent (eg, the browser) is used only by the user who you originally authenticated. “记住我”实质​​上是基于这样的假设,即用户代理(例如浏览器) 由您最初进行身份验证的用户使用。 Can you or your user be sure of that? 您或您的用户可以确定吗? (This is why websites require you to opt-in to "remember me" - when you check that box you're promising that nobody who doesn't have authorized access to your user account has access to your user-agent.) It's not hard to see that this is pretty much essentially insecure. (这就是为什么网站要求您选择“记住我”的原因-当您选中此框时,您承诺没有授权访问您的用户帐户的任何人都不能访问您的用户代理。)很难看出这在本质上是不安全的。 You can sign or encrypt your cookies, but unless you know that the user-agent is only accessible by the user you authenticated, you don't know that the user who visits your website the next time is authorized to access the original user's account. 您可以对Cookie进行签名或加密,但是除非您知道只有经过身份验证的用户才能访问用户代理,否则您不知道下次访问您网站的用户有权访问原始用户的帐户。

If you're using omniauth , then you're essentially relying on some 3rd party to authenticate your users for you, either as a Relying Party as defined in by the OpenID Connect specification, or using some kind of non-standard authentication scheme on top of OAuth 1 or 2. What you're essentially asking is "Can I securely authenticate a user via a 3rd party just once and then safely assume that any time the same user-agent visits my site, it's the same user?" 如果您使用的是omniauth ,那么您实质上是依靠某个第三方来验证您的用户身份,或者作为OpenID Connect规范中定义的依赖方,或者在顶部使用某种非标准的身份验证方案OAuth 1或2。实际上,您要问的是:“我能否通过一次第三方安全地对用户进行身份验证,然后安全地假设任何时候同一用户代理访问我的网站,就是同一用户?”

The answer is NO . 答案是否定的

But admittedly, there's a trade-off here between security and usability, and some people might think the risks (if the user's account isn't that sensitive) are outweighed by the usability benefits. 但不可否认,在安全性和可用性之间需要权衡取舍,有些人可能会认为可用性带来的好处超过了风险(如果用户的帐户不是那么敏感)。 However, if you're relying on a 3rd-party provider to authenticate your users, then the usability difference is almost literally zero . 但是,如果您依靠第三方提供程序来验证用户身份,则可用性差异几乎为零 If the user has already authorized your application on google, facebook, or whatever other provider, and if they have a current session with that provider, then when they click the "log in with [provider]" link on your site, they can be logged in with no additional interaction from the user. 如果用户已经在google,facebook或任何其他提供者上授权了您的应用程序,并且与该提供者进行了当前会话,则当他们单击您网站上的“使用[提供者登录]”链接时,他们可以登录,无需用户进行任何其他交互。 No passwords or usernames to remember and enter, nothing. 无需记住和输入密码或用户名,什么都没有。 So the worst that can happen is they have to log in to google, facebook, or whatever, if they aren't already. 因此,可能发生的最糟糕的情况是他们必须登录google,facebook或其他(如果尚未登录)。

What's more, if you do this, you get more assurance that the user is who they say they are. 更重要的是,如果你这样做,你会得到更多的保证用户是谁,他们说他们是。 Each time your user "signs in" with an OpenID provider, you get an id token that says who they are, that they were authenticated by by the provider, when that authentication event took place, etc. So you're not just assuming they're the user with a particular provider uid, you're trusting the provider's assertion that they are. 每次您的用户使用OpenID提供程序“登录”时,您都会获得一个ID令牌,该令牌表明他们是谁,提供程序对他们进行了身份验证,何时发生了身份验证事件等。因此,您不仅在假设他们是具有特定提供者uid的用户,则您信任提供者的身份。 Of course, even this is not perfectly secure, because it's possible the user's provider account is compromised, or in theory the provider could be untrustworthy. 当然,即使这也不是完全安全的,因为用户的提供者帐户可能会受到损害,或者从理论上讲,提供者可能是不可信的。 But it's still an improvement over "remember me." 但这仍然比“记住我”要好。

TL;DR "Remember me" is inherently not secure, and offers no meaningful usability improvement over requiring sign in via an OpenID provider on each visit. TL; DR“记住​​我”本质上是不安全的,并且与每次访问时都要求通过OpenID提供程序登录相比,没有提供有意义的可用性改进。 Don't do it. 不要这样

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM