如何使用 Java Spring 安全性构建功能齐全的 RESTful API

Posted

技术标签:

【中文标题】如何使用 Java Spring 安全性构建功能齐全的 RESTful API【英文标题】:How do I build a full-functional RESTful API using Java Spring security 【发布时间】:2018-05-27 02:37:04 【问题描述】:

我正在为一个完全依赖于这个 API 的应用程序构建一个 REST API(意味着根本没有前端)。所以我发现自己在两点上苦苦挣扎:

1.如何使用 REST 实现身份验证/注册并执行需要身份验证的操作?

嗯,我知道像 Instagram 这样的应用程序有一个特殊的页面,用户可以在其中生成 access_token 并不受限制地使用 Instagram API(需要身份验证)。但就我而言,我所能做的就是创建一个这样的 REST 请求

?action=generateToken&userName=someName&password=somePassword

如果用户名和密码正确,我想得到 access_token 作为响应。 在这里注册也是一样

?action=register&userName=someName&password=somePassword

在这里我收到问候消息和 access_token

问题是我应该如何使用这些令牌存储、生成、刷新、操作?我应该有一个单独的数据库,其中存储令牌本身和相关的用户(ID)吗?当然,我应该在 N 分钟后删除这些令牌。我应该将令牌存储多长时间?否则,任何以某种方式窃取令牌的人都可以访问所有用户的功能。我该怎么做?

如果我做对了,任何需要用户识别的操作都可以这样完成

?action=sendMessage&access_token=someToken&recipientId=100&message=TestAuthOut!

其中 access_token 是生成的令牌

2。如何形成一个以对象数组作为输入的 REST 请求? 我的意思是执行如下操作:

?action=createNewVetClinic&vetClinicName=someName&doctors=doctor1: name = "doctor1", occupation="surgeon", salary=100, doctor2: name = "doctor2", occupation="dentist", salary=80

是否可以创建这样的请求?我知道非常菜鸟的问题,但无论如何

【问题讨论】:

不要在 GET 请求的 URL 参数中包含凭据 令牌有两种——访问令牌和会话令牌。访问令牌不应过期 - 用户应进行身份验证并请求令牌;然后,该令牌应至少作为标头包含在每个请求中。将凭据作为 URL 参数发送是一个坏主意。在理想情况下,身份验证是通过客户端证书进行的——TLS 本身处理身份验证的方式。 REST 应用程序应该是无状态的,因此不应使用会话令牌。 进一步 ?action=XXX 不是 REST - 它是“J. Doe 的神奇 API”。 REST 需要映射到资源的 URL 和 HTTP 动词来执行操作,例如 GET /token 将创建一个令牌,DELETE /token 将使令牌无效。 最后一个问题是PUT /vet-clinic,请求正文中有诊所的 JSON 定义。 【参考方案1】:
    如何使用 REST 实施身份验证/注册并执行需要身份验证的操作?

保护 REST 应用程序的普遍共识是在 HTTP 标头中而不是在请求负载中发送凭据或访问令牌,并将它们包含在每个请求中,因为 REST 应该是无状态协议。 Authorization 标头通常用于此,格式为Authorization: <Scheme> <Payload>,其中<Scheme> 是授权方案,<Payload> 通常是方案相关的。常用的授权方案包括:

Basic <base-64-encoded-credentials>

此方案的有效负载是 Base64 编码的凭据,格式为 <username>:<password>。应用程序应检查标头,提取凭据,并根据凭据存储(您的用户数据库或其他)验证它们。这种方法的缺点是凭据以纯文本形式发送到服务器;不过,强制 HTTPS 协议访问 REST API 在很大程度上缓解了这个弱点。

Bearer <token>

通常用于提供以前生成的访问令牌。它们的优点是在生成访问令牌后不需要将凭据发送到服务器。同样,应用程序检查令牌,从中提取用户授权信息,并据此授权用户。如果您的应用程序在服务器端维护用户会话,那么您可以使用此方案发送会话令牌;但是,不推荐这种方法,因为它不可扩展。相反,可以使用各种加密方法将用户身份验证信息嵌入到访问令牌本身中,以便令牌可以在服务器上进行解密和验证,而不需要会话存储,同时在客户端仍然具有很高的抗篡改能力边。常见的此类方法包括 SAML 和(我最喜欢的)JWT。所有使用承载的方案都依赖于某种/generate-access-token API 端点。

关于如何集中拦截和授权所有API请求,我可以参考my earlier answers之一(它是Spring Boot特有的,但也可以很容易地适应普通的Spring MVC应用程序)

【讨论】:

以上是关于如何使用 Java Spring 安全性构建功能齐全的 RESTful API的主要内容,如果未能解决你的问题,请参考以下文章

网易云易盾CTO朱浩齐:我们是如何用AI赋能内容安全?

网易云易盾朱浩齐:视听行业步入强监管和智能时代

网易云易盾朱浩齐:视听行业步入强监管和智能时代

寻找一个简单的 Spring 安全示例 [关闭]

如何使用 xml 配置文件、JAVA、Spring 安全性对 LDAP 用户进行身份验证

Java Spring 技术栈构建前后台团购网站