使用令牌(Java)保护REST Web服务

Ted*_*ddy 3 java security encryption rest web-services

这个问题在某种程度上与以下相关问题有关.但是,我需要更清楚一些方面和一些其他信息.请参阅: REST Web服务身份验证令牌实现

背景:

  • 我需要使用令牌为REST Web服务实现安全性
  • Web服务旨在与Java客户端一起使用.因此,凭据的表单身份验证和弹出窗口无用.
  • 我是REST安全和加密的新手

这是我迄今所理解的:

第一次请求:

  1. 用户建立https连接(或容器使用301确保https)
  2. 用户POST用户名和密码登录服务
  3. 如果凭证有效,我们:
    • 生成随机临时令牌
    • 将随机令牌存储在服务器上,将其映射到实际用户名
    • 使用仅为服务器所知的对称密钥加密令牌
    • 哈希加密的令牌
    • 将加密的令牌和哈希发送到客户端

对于后续请求:

  1. 客户端发送此加密令牌和哈希组合(使用基本的用户名字段?)
  2. 我们确保加密的令牌不会被哈希篡改,然后解密
  3. 我们检查session-tracking-table中的解密令牌是否有未过期的条目,并获取实际的用户名(到期时间由代码管理?)
  4. 如果找到用户名,则根据允许的角色配置允许的操作

更多细节:

  1. 由于客户端是java客户端,因此第一个请求可以是包含凭据的POST.但是,这似乎可能会在https建立之前公开凭据.因此,是否应该对安全资源进行虚拟GET,以便首先建立https?
  2. 假设上面是必需的,第二个请求是带有凭据的LoginAction POST.此请求是手动处理的(不使用容器的授权).这是正确的吗?
  3. 上面的LoginAction返回用户加密令牌+哈希的组合
  4. 用户将其设置为BASIC身份验证机制使用的标头(字段用户名)
  5. 我们实现了一个JAASRealm来解密和验证令牌,并找到允许的角色
  6. 其余的授权过程由具有web.xml中定义的WebResourceCollection的容器负责

这是正确的方法吗?

Sil*_*Fox 6

为什么不将它简化为以下内容?

第一次请求:

  1. 用户建立与服务器的HTTPS连接(服务不在任何其他端口上侦听)和POST登录服务的凭据.
  2. 服务器回复HSTS标头以确保所有进一步的通信都是HTTPS.
  3. 如果凭证有效,我们:
    • 生成使用CSPRNG安全生成的随机临时令牌.使这长得足够安全(128位).
    • 将随机令牌存储在服务器上,将其映射到实际用户名.
    • 将随机令牌发送到客户端

对于后续请求:

  1. 客户端通过HTTPS在自定义HTTP标头中发送令牌.
  2. 令牌位于数据库中并映射到用户名.如果找到基于允许的角色和允许的操作的访问权限.
  3. 如果未找到,则认为用户未经身份验证,并且必须再次使用登录服务进行身份验证才能获得新令牌.

在服务器端,令牌将以失效日期存储.在每次访问服务时,将更新此日期以创建滑动到期日期.每隔几分钟就会有一个作业删除已过期的令牌,并且检查令牌以查找有效会话的查询只会检查那些未被认为已过期的查询(如果计划的作业因任何原因失败,则会阻止永久会话).

不需要对数据库中的令牌进行散列加密 - 除了通过默默无闻安全性之外,它不会增加真正的价值.你可以哈哈哈哈.这可以防止设法进入会话数据表的攻击者劫持现有用户会话.