2017-05-04 68 views
0

OAuth2谈话中涉及多方参与。从文章here我是否需要使用OAuth 2访问令牌来保护我的API端点(资源)?

enter image description here

想想看,我有一个为restaurants有数据,以及具有与它的API的应用程序考虑 如下图。我们称之为restaurant的API。让我们分配本例中

User - our chefs, who have some recipes in restaurant 

Application - Web client written in HTML5, JS, CSS that our Users use to interact with APIs 

OAuth Endpoint - Google (who acts as Authorization Server) 

API - My application API keeping all data for chefs 
的背景下一些作用,每一方

Implicit工作流(按照上面的链接图)规定的Application得到access token,然后Application(浏览器)调用API(我申请厨师食谱)并获取数据。

问题

  • 我不应该secure我的应用程序的端点或者说只相信accesssTokens?是的,信托建立在ApplicationOAuth Endpoint(Google)之间,但是没有trust开发APIApplication确认accessTokenOAuth Endpoint(Google)的有效性?

  • 如果我要保护我的应用程序API终点,我将有一个/login终点为我APIs在我的应用程序接受accessTokens,验证,并创建一个基于JWT头,为客户作进一步的沟通与保护资源,如/recipes使用。

期待您的想法在这里。
在此先感谢

回答

1

TL; DR-不要盲目信任访问令牌。要求Google公开与其关联的用户/电子邮件以及生成时使用的客户端ID。您仍然可以提供一个/login端点,以实现可扩展性。

让我们处理核心安全第一

OAuth是一个代表团的协议,而不是一个身份验证协议。从the OAuth website引用:

OAuth 2.0规范定义了委托协议[...] OAuth用于各种应用程序,包括提供用户身份验证的机制。 [...]我们再说一遍,要清楚:

OAuth 2.0不是一个身份验证协议。

因为它不是一个身份验证协议,您的应用程序/ API永远不会知道用户是谁。它只是得到一个令牌。在这种情况下的委派意味着,OAuth通过让用户对App B进行身份验证,然后将该令牌传递回App A,让App A请求访问属于某个用户的App B中的资源。在您的示例中,它可以为您的网络应用提供用户(厨师)拥有的Google资源(电子邮件,照片等 - 取决于所需的scope)。

请注意,这不是你在这里做的,因为你正在访问由管理的资源,而不是你的应用,而不是Google。特别是,正如您正确识别的那样,访问令牌对您的API没有任何意义。我可以给它一个随机字符串。

你也许会使用以下方案:

  • 在你的问题中所述落实隐式。
  • 让API服务器使用Google验证访问令牌,并要求Google提供与令牌关联的名称或电子邮件。这将是实际登录Google的用户的身份,然后您可以决定是否授予该用户权限。

这种方法的问题在于许多应用程序在Google上使用OAuth,所以很多应用程序都会让Google访问令牌不属于您的应用程序。你怎么能区分这个区别?

当您向访问令牌提供时,您可以要求Google向您提供在生成此令牌时提供的客户端ID(请参阅您的图表指示客户端ID是如何发送的?) 。由于该客户端ID唯一标识了您的应用,因此您的API可以告诉它只有来自您的应用的令牌。请注意,OAuth流程的这个关键部分在移动应用程序中有很大不同,这就是隐式流程不应用于移动应用程序的原因(但对于Web应用程序来说它没问题)。

请注意,您的客户端ID应该被视为常识(例如,它可以在执行此流程的计算机上的.js文件中找到),但它不能被欺骗,因为作为OAuth流程的一部分,用户的浏览器将被重定向到Google预先配置并且属于您的应用的网址。因此,即使恶意应用程序使用您的客户端ID,Google仍会将令牌发送给您的应用程序。上述

其他实用性

需要你在每个API调用发给谷歌的电话,或至少缓存有效的访问令牌(这意味着你保持状态,这是实现可伸缩性的无赖)。如果您想避免这种情况,您可以创建一个生成JWT的端点/login。请注意,您仍然需要在登录时验证访问令牌。

+0

感谢您的回复。我相信而不是'accssTokens',最好是获得'id_token',然后使用'Google Java客户端库'(我的服务器是用'Java'编写的)在'/ login'端点上验证它,网络请求(尽管附加依赖)。请参阅https://developers.google.com/identity/sign-in/web/backend-auth – daydreamer

+0

@daydreamer有意义,如果您可以在没有任何网络请求的情况下在本地验证它。对此并不熟悉。只要确保遵循所有返回的字段的所有验证步骤 – YSK

+0

当然,听起来不错。谢谢! – daydreamer

相关问题