Java RESTAPI授权类型

Java RESTAPI授权类型,java,api,rest,jersey,Java,Api,Rest,Jersey,我已经读了很多关于提供RESTAPI访问的方法的书,但我仍然不能决定使用什么 在我的例子中,我正在编写一个restapi,它将被移动应用程序(android和iOS)的用户使用,因此我不提供或要求第三方访问,这使我认为我不必使用OAuth。 但是,我考虑了如何从多个设备访问一个用户的帐户,以及如何提供脱机访问 我需要考虑的另一个问题是如何限制API访问,例如,如果使用API令牌,令牌过期和续订的最佳做法是什么?有两件事需要保护/验证 客户端应用程序被授权使用该服务 用户有权访问个人数据 应用

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

在我的例子中,我正在编写一个restapi,它将被移动应用程序(android和iOS)的用户使用,因此我不提供或要求第三方访问,这使我认为我不必使用OAuth。 但是,我考虑了如何从多个设备访问一个用户的帐户,以及如何提供脱机访问


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

有两件事需要保护/验证

  • 客户端应用程序被授权使用该服务
  • 用户有权访问个人数据
应用程序身份验证 移动应用程序是不受信任的客户端。即使您不允许任何人访问应用程序源,您也必须知道任何类型的授权秘密或机制都是不安全的,可能来自被黑客攻击的应用程序或其他模拟应用程序行为的恶意工具

为了验证应用程序,您所能做的只是拥有一个客户端密码,而不是一个客户端密码。例如

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

Reply method(String client_id) {
   if (!client_id in ["andoid", "ios"])
       return Unauthorized();
}
您可以将该模式更改为更难猜测的模式,但您所做的任何事情都可以归结为相同的安全级别

用户身份验证 保护用户数据至关重要,幸运的是这是可能的。关键的区别在于,这个秘密不是静态地硬编码到应用程序中的,它只为用户所知

验证用户身份的一个“简单”方法是使用他们拥有的其他帐户。类似的模式允许您完全做到这一点

基本上,您可以将身份验证委托给其他服务。并获取(每个服务)唯一的用户id,您可以在代码中使用该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);
}
攻击者仍然可以从某些邪恶的应用程序使用您的服务,但无法访问他无论如何都无法访问的帐户


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

您的问题中有几个主题:

  • OAuth2对于Internet上公开的内部API有什么好处
  • 我应该如何管理代币
  • 用户如何通过多个设备获得访问权限
  • 用户如何进行脱机访问
我将在下面讨论这些问题

Oauth2

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

管理代币

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

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

多设备

每个令牌可以与特定的用户和设备相关联,以允许在多个设备上进行访问。这意味着每个设备必须唯一标识,通常使用IMEI代码。这使得一次撤销特定设备或用户的所有令牌变得很容易

脱机访问

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

  • 根据编辑的类型或用户的角色,一个编辑会覆盖另一个编辑
  • 忽略最后一次编辑,或提供最后一次编辑的分辨率
  • 某些类型的编辑可能会自动“合并”
  • 等等

另一个好的简单策略是禁止脱机时进行所有编辑。

一个很好的答案!这澄清了我一直想知道的所有事情,并整理了我的想法。就我开始用令牌实现RESTAPI而言,这对我来说非常合适,只需做一些调整。