REST API授权类型

时间:2014-11-26 12:35:50

标签: java api rest jersey

我已经阅读了很多关于提供REST API访问的方法,但我仍然不能决定使用什么。

在我的情况下,我正在编写一个REST API,将由移动应用程序(android和iOS)的用户使用,因此我不提供或要求第三方访问,这让我觉得我没有必须使用OAuth。 但是,我考虑了如何从多个设备访问一个用户的帐户以及如何提供脱机访问。

我的另一个考虑因素是如何限制API访问,例如,如果使用API​​令牌,那么令牌的过期和续订的最佳做法是什么?

2 个答案:

答案 0 :(得分:1)

您的问题中有几个主题:

  • OAuth2对于在Internet上公开的内部API有什么好处?
  • 我该如何管理令牌?
  • 用户如何通过多个设备获取访问权限?
  • 用户如何进行离线访问?

我在下面讨论这些问题。

的oauth2

OAuth2为不同复杂程度的多种身份验证方案提供标准化协议。最复杂的用例之一是授权代码授权'允许资源所有者(用户)通过中介(授权服务器)授予对客户端应用程序的特定访问权限的流程。当您使用google'登录时会发生这种情况。使用OAuth2而不是自制解决方案的优势在于协议对所有各方都很清楚,并且不太可能包含基本缺陷。缺点可能是协议不灵活,因此某些自定义方案可能难以在OAuth2的范围内得到支持。如果您不需要任何典型的OAuth2场景(或者要求使用OAuth2的利益相关者),那么我建议不要从头开始,而是自己实现一个简单的令牌方案。 / p>

管理令牌

管理API访问的最常用方法是使用令牌。用户登录时会生成令牌,通常使用HTTPS上的用户名和密码。令牌保留在服务器上,必须由应用程序在每个请求中提供。这类似于Web应用程序中使用的会话ID,它由服务器上的应用程序容器自动生成和处理,并通过cookie或请求参数传递。 API令牌通常由应用程序本身的安全层处理,持久存储在数据库中并通过“授权”传递。报头中。

令牌应具有到期日期。应该确定最佳间隔时间以及令牌续订是自动的(每次用户访问API时)还是显式的(强制用户在到期后重新输入凭据)。这取决于应用程序的类型和所需的安全级别。也可以在服务器上手动撤销令牌。

多个设备

每个令牌都可以与特定用户和设备相关联,以允许在多个设备上进行访问。这意味着每个设备必须通过IMEI代码进行唯一标识。这样可以轻松地立即撤销特定设备或用户的所有令牌。

离线访问

提供离线访问的典型方法是在设备上缓存相关数据。例如,谷歌地图应用程序允许您使地图的特定区域可脱机使用。为了避免过于陈旧的数据,您可以跟踪令牌的到期日期,并在此日期之后使缓存的数据无效。需要注意的一个问题是用户处理离线编辑。当设备再次联机时,必须处理这些编辑。当遇到对同一数据的同时编辑时,需要一种策略来解决冲突,例如:

  • 根据编辑类型或用户角色
  • ,一个编辑会覆盖另一个编辑
  • 忽略或提供最后一次编辑以解析最后一个编辑
  • 某些类型的修改可能会被合并'自动

另一个好的和简单的策略是在离线时禁止所有编辑。

答案 1 :(得分:0)

您要保护/验证有两件事

  • 客户端应用程序有权使用该服务
  • 用户有权访问个人数据

应用认证

移动应用程序是不受信任的客户端。即使您无法访问应用程序源,您也必须预期任何类型的授权机密或机制都是不安全的,并且可能来自被黑客入侵的应用程序或其他模仿应用程序行为的恶意工具。

要对应用进行身份验证,您所能做的只是拥有client id,而不是客户端密码。 E.g。

http://service.com/rest?client_id=android

Reply method(String client_id) {
   if (!client_id in ["andoid", "ios"])
       return Unauthorized();
}

您可以将该架构更改为更难以猜测的内容,但您执行的操作可以归结为相同的安全级别。

用户身份验证

保护用户数据至关重要,幸运的是。关键的区别在于秘密不是静态硬编码到应用程序中,只有用户知道。

One" easy"验证用户的方法是使用他们拥有的其他帐户。像http://openid.net/connect/faq/这样的模式可以让你做到这一点。

您基本上将身份验证委派给其他服务。并获得一个(每个服务)唯一用户ID,您可以在您的代码中使用它作为所有用户数据的关键。攻击者无法伪造,因为您的服务器可以通过询问其他服务来验证令牌是否有效。看起来大致像

http://service.com/rest?client_id=android&user_token=aasjkbn9nah9z23&user_auth_service=facebook

Reply method(String client_id, user_token, user_auth_service) {
   if (!client_id in ["andoid", "ios"])
       return Unauthorized();
   authenticated_user_id = user_auth_service.getUserIdOrFail(user_token);
   accessDatabase(authenticated_user_id);
}

攻击者仍然可以使用来自某个恶意应用程序的服务,但是无法访问他无法访问的帐户。

如果您将访问令牌硬编码到应用程序中,您最好不要使它们过期,或确保以某种方式在应用程序中专门处理该案例。总是有用户使用过时的应用版本。

相关问题