了解如何保护 REST API 与编写 API 本身一样重要。大多数 REST API 都是基于 HTTP 协议的,任何有互联网连接的用户都可以访问它们,坏用户也可以。编写安全的 API 以保护业务非常重要。
在开始保护 RESTful API 之前,让我们先了解一下作为开发人员我们有哪些选择?什么适合我们的用例?
在进入主要讨论之前,让我们弄清楚什么是身份验证和什么是授权。
在简单的英语中,身份验证 是确定“用户确实是他声称的人”的过程。在技术术语中,它是通过用户名/密码或任何类似机制登录系统的过程,例如从 SSO 登录收到的指纹扫描、安全令牌、安全问题或 SAML 令牌。必须有一些东西可以从其他人中识别用户。
一旦用户进入系统,授权指的是确定“允许用户做什么”以及不允许做什么的规则,例如普通用户可以在任何公共组中发帖,但只有编辑角色的用户才能删除某些内容。授权通常被视为系统管理员对权限的介绍性设置,以及在用户访问系统时检查已经设置的权限值。
当我们保护 RESTful Web 服务时,我们需要兼顾这两个因素。这两个概念是完全正交和独立的,但都是安全设计的核心,未能正确理解任何一个都会增加系统受损的机会。
有多种方法可以在 Java 中保护 RESTful API。让我们来看看 4 个最受欢迎的选择:
它是所有技术中最简单的,也可能是最常用的。您使用登录/密码表单——这只是基本身份验证。您输入您的用户名和密码并将表单提交到服务器,应用程序将您识别为用户——您被允许使用该系统——否则您会出错。
此安全实现的主要问题是凭据以简单的方式从客户端传播到服务器。凭据仅在传输过程中使用 Base64 编码,但未以任何方式加密或散列。这样,任何嗅探器都可以通过网络读取发送的数据包。
因此,HTTPS 通常优先于基本身份验证或与基本身份验证结合使用,后者使与 Web 服务器的对话完全加密。最好的部分是没有人甚至可以从外部猜到 Basic Auth 正在发生。
这种身份验证方法使用哈希算法对用户输入的密码(称为密码哈希)进行加密,然后再将其发送到服务器。显然,这使其比基本身份验证方法安全得多,在基本身份验证方法中,用户密码以明文形式传输,任何拦截它的人都可以轻松读取。
更多参考: 生成加密密码
java 中也有许多这样的哈希算法,它们可以证明对密码安全非常有效,例如 MD5、SHA、BCrypt、SCrypt 和 PBKDF2WithHmacSHA1 算法。
请记住,一旦此密码哈希生成并存储在数据库中,您就无法将其转换回原始密码。每次用户登录应用程序时,您都必须重新生成密码哈希,并与存储在数据库中的哈希匹配。因此,如果用户忘记了他/她的密码,您将不得不向他发送一个临时密码并要求他使用新密码进行更改。好吧,这是当今的普遍趋势。
这是一种通过证书在服务器和客户端之间建立信任协议的机制。它们必须由建立的机构签名,以确保为身份验证提供的证书是合法的,这称为 CA。
使用这种技术,当客户端尝试访问受保护的资源时,它不会提供用户名或密码,而是向服务器提供证书。该证书包含用于身份验证的用户信息,包括安全凭证,以及唯一的公私密钥对。服务器然后通过 CA 确定用户是否合法。此外,它必须验证用户是否有权访问该资源。这种机制必须使用 HTTPS 作为通信协议,因为我们没有安全通道来防止任何人窃取客户端的身份。
您可以找到在官方 oracle 文档中生成安全证书。
如果您曾经开发过通过云与其他应用程序交互的应用程序,例如facebook 集成或 twitter 身份验证等,那么您已经使用过它。他们要求您提供 API 密钥和 API 机密以正确识别您的身份。这些 API 密钥和秘密是一些无法猜测的随机编码字符串。
为了解其工作原理,假设您正在使用 Flickr(照片共享应用程序)并希望使用它的 REST API 发布您的一些照片。您按照 Flickr 文档中的记录构建请求,然后发送它。
然后,当收到请求时,Flickr 通过使用属于用户的密钥从 API 密钥中读取信息来对用户进行身份验证。一旦这些验证成功,服务器就会将响应传递给客户端。因此,我们获得了包含最近在 Flickr 中发布的所有照片的响应。
您会注意到,通过这种方式,您可以使用提供商的 API 轻松创建应用程序。此外,提供商将允许您进行身份验证、访问公共信息。
如果有人开始不尊重协议,例如发送垃圾流量或任何违反政策的行为,提供商会撤回 API 密钥并防止滥用其 API。
除了上述概念外,您通常还需要使用以下方法来保护公司中的 RESTful API。
javax.ws.rs.core.SecurityContext
接口为请求提供对安全相关信息的访问,与 javax.servlet.http.HttpServletRequest
非常相似。
您可以通过使用 javax.ws.rs.core.Context
注释将实例注入类字段、setter 方法或方法参数来访问 SecurityContext,例如在下面的代码中,sc.isUserInRole()
用于检查用户的授权。
@GET @Produces("text/plain;charset=UTF-8") @Path("/hello") public String sayHello(@Context SecurityContext sc) { if (sc.isUserInRole("admin")) return "Hello World!"; throw new SecurityException("User is unauthorized."); }
该技术广泛用于企业应用程序,用于验证已验证用户的角色和职责 - 对于任何特定操作。 JAX-RS 为此提供了以下注释。
注释的使用示例可以是:
@RolesAllowed("ADMIN") @PUT @Path("/users/{id}") public Response updateUserById(@PathParam("id") int id) { //Update the User resource UserDatabase.updateUser(id); return Response.status(200).build(); }
更多参考: JAX-RS 身份验证和授权示例
让我们在为 RESTful Web 服务设计安全性时记下一些要点。
让我知道您对组织中如何保护 RESTful 网络服务 的想法和经验。
快乐学习!!
地址:https://www.cundage.com/article/rest-api-security-guide.html