oauth2 是不是只有在有第三方授权时才使用?

Posted

技术标签:

【中文标题】oauth2 是不是只有在有第三方授权时才使用?【英文标题】:is oauth2 only used when there is a third party authorization?oauth2 是否只有在有第三方授权时才使用? 【发布时间】:2017-04-18 19:02:20 【问题描述】:

我现在正在阅读有关 oauth2 的信息,并试图了解它的用途。从我阅读的所有资源来看,oauth2 似乎仅在具有一些用户的 web 应用程序(例如游戏应用程序)并且该应用程序想要访问用户的 Facebook 或 Google 数据(某种数据,如姓名或电子邮件,等等)。这部分我很清楚。但是,我仍然不清楚的事情如下:

    例如:如果我有一个 web 应用程序,并且我希望我的 web 应用程序的用户使用他们的登录名和密码登录到 web 应用程序(就像使用 gmail 一样)而不使用任何第三方。 oauth2 是否也提供这种类型的授权?

    我见过 webapps,它们只允许用户使用 ID 和密码注册,然后他们对密码进行加盐并将加盐存储在数据库中。因此,当用户稍后登录时,他们会对用户输入的密码进行加盐,并将此加盐与数据库中的加盐(在注册期间创建)进行比较。如果相等,则用户登录。这对我来说根本不像是誓言。那么如果这不是oauth,这是什么标准呢?还有像这样的“直接登录”还有其他标准吗?

    假设我希望允许用户注册并登录我的网站,但让他们通过第三方(如 Facebook 或 Google)登录。这只是出于授权目的,并假设我的应用程序没有计划在他们的 Facebook 上发布或请求他们的 Facebook 数据,除非我可能想使用他们的 Facebook 电子邮件作为我的 webapp 的用户 ID。 oauth2 是否提供这种类型的授权?

很抱歉这些天真的问题,因为我最近才读到关于 oauth 的内容。

【问题讨论】:

【参考方案1】:

    对于没有第三方的注册/登录,正如 Kevin 指出的那样,每个编程/Web 框架通常都带有一个流行的库,它会生成所有的注册/登录页面、数据库表,流量等,为您服务。然后,您唯一要做的就是在您需要确定用户是谁时,在后端代码中调用库提供的返回当前登录用户的方法。

    正如您所指出的,使用加盐密码方案与您的 OAuth2 完全无关。它是一种广泛使用的本地身份验证方案,因为它有很多好处,但我在这里只强调 2:

    一个。当通过 Internet 从用户传输到服务器以进行身份​​验证时,密码不是以明文形式发送,而是以散列格式发送。这样即使被窃听,密码也不会泄露。

    b.由于每个密码都是加盐的,即使是 2 个相同的密码也不会具有相同的哈希值,因为每个密码都有不同的加盐值。因此,即使密码散列被窃听,它也不能在用户使用相同密码的另一个服务中重复使用,因为其他服务期望使用不同的盐生成密码散列。

    OAuth2 完全是关于授权(请求用户允许在另一个 Web 服务上代表她执行某些操作,例如,请求用户允许访问她在 Facebook 上注册的电子邮件地址)。将其用于身份验证可能是不安全的(对于 OAuth2 隐式流)。为什么? OAuth2 的最终结果是与权限相关联的访问密钥,例如“访问电子邮件地址的权限”。当您使用 OAuth2 结果(访问密钥)进行身份验证时,这意味着您正在假设“访问电子邮件地址的权限”意味着用户成功通过 Facebook 进行了身份验证,她做到了,所以看起来很好。但是,想象一下其他站点是否也像您一样使用 OAuth2 进行身份验证;如果它收到带有“访问电子邮件地址的权限”的访问密钥,它将假定您已通过 Facebook 进行身份验证,因此它将授予您访问属于该电子邮件地址的帐户的权限。您实际上可以使用从用户那里获得的访问密钥,并以她的身份登录其他站点,反之亦然。

要使用 OAuth2 进行身份验证,您需要将其与 OpenID Connect (OIDC) 一起使用,因为 OAuth2-OIDC 的最终结果包含一个 id_token,其中 aud(受众)字段标识访问密钥的对象(https://openid.net/specs/openid-connect-core-1_0.html#IDToken ),这可以防止访问密钥在不打算使用的地方被重用。带有易于理解的图表的完整解释在这里:https://www.slideshare.net/KhorSoonHin/the-many-flavors-of-oauth/36?src=clipshare

另一个非常简单但可能令人不安的使用 OAuth2 登录的安全意识方法是使用资源所有者密码凭据,您的网站充当用户和 OAuth2 提供者 (Facebook) 之间的中间人。

    显示“使用 Facebook 登录”按钮 当用户点击按钮时,提示用户输入 Facebook 用户名/密码 使用用户名/密码登录 Facebook 以确认身份验证并获取访问令牌。

如果您没有时间深入阅读有关 OAuth2 的内容,或许这种对所有 OAuth2 流程的并排比较会有所帮助。

这是https://blog.oauth.io/introduction-oauth2-flow-diagrams/的礼貌

【讨论】:

【参考方案2】:

    您可以像这样使用 OAuth 进行本地登录,但您不必这样做。这可能会更容易,具体取决于可用的库,如果您预计将来将您的服务提供给第三方,这可能是有意义的。但是,对于许多网站来说,使用 OAuth 进行本地登录可能有点过头了。

    当不同的参与者需要说一种共同的语言以便他们可以互操作时,标准是最有用的。对于本地登录,您不需要标准,因为您没有与任何第三方进行交互。许多 Web 框架在相同的基本流程中包含自己的变体。

    当您实际上不需要任何授权(访问第三-派对资源)。它确实可以这样使用,但是很多人会警告它,因为它不是为此而设计的,并且在这种情况下存在一些安全漏洞。例如,请参阅Common pitfalls for authentication using OAuth。

【讨论】:

凯文,谢谢。您是否知道任何用于本地登录的知名现有框架/库?还是不存在这样的东西,每个网站都必须实施自己的?我最近在阅读有关 JWT(jason web 令牌)的信息,但仍在试图弄清楚这是否是用于本地登录的东西。 JWT 更像是一个标准而不是一个框架。 @Simo:大多数 web 框架将包含某种身份验证实现,并且许多还将支持添加额外功能的第三方包。举个我最熟悉的例子,Django(Python web框架)有自己的authentication system,也有第三方项目添加OAuth、integrated social logins等。

以上是关于oauth2 是不是只有在有第三方授权时才使用?的主要内容,如果未能解决你的问题,请参考以下文章

Spring security OAuth2.0认证授权学习第四天(SpringBoot集成)

Spring security OAuth2.0认证授权学习第四天(SpringBoot集成)

OAuth 2.0 授权认证详解

Erlang在socket中接受连接只有在有多层进程时才会失败

Spring Security OAuth2

OAuth2.0标准授权管理流程