背景:
>我需要使用令牌为REST Web服务实现安全性
> Web服务旨在与Java客户端一起使用.因此,形式
凭据的身份验证和弹出窗口无用.
>我是REST安全和加密的新手
这是我迄今所理解的:
第一次请求:
>用户建立https连接(或容器确保使用https
301)
>用户POST用户名和密码登录服务
>如果凭证有效,我们:
>生成随机临时令牌
>将随机令牌存储在服务器上,将其映射到实际用户名
>使用仅为服务器所知的对称密钥加密令牌
>哈希加密的令牌
>将加密的令牌和哈希发送到客户端
对于后续请求:
>客户端发送此加密令牌和散列组合(使用
用户名字段基本?)
>我们确保加密的令牌不会被哈希篡改
然后解密它
>我们在会话跟踪表中检查解密的令牌
未过期的条目并获得实际的用户名(到期管理
按代码?)
>如果找到用户名,则根据允许的角色,允许的操作
配置
更多细节:
>由于客户端是java客户端,因此第一个请求可以是POST
包含凭据.但是,这看起来可能会暴露出来
https建立之前的凭据.因此应该
对安全资源有一个虚拟GET,以便https
先建立?
>假设上面是必需的,第二个请求是LoginAction POST
凭证.此请求是手动处理的(不使用
容器的授权).这是正确的吗?
>上面的LoginAction返回用户加密的组合
令牌哈希
>用户将其设置为BASIC身份验证使用的标头
机制(字段用户名)
>我们实现了一个JAASRealm来解密和验证令牌,并找到
允许的角色
>剩余的授权过程由容器处理
使用web.xml中定义的WebResourceCollection
这是正确的方法吗?
解决方法:
为什么不将它简化为以下内容?
第一次请求:
>用户建立与服务器的HTTPS连接(服务不会监听任何服务器
其他端口)和POST凭据登录服务.
>服务器回复HSTS header以确保所有进一步的通信
是HTTPS.
>如果凭证有效,我们:
>生成一个使用CSPRNG安全生成的随机临时令牌.使其足够长以保证安全(128位).
>将随机令牌存储在服务器上,将其映射到实际用户名.
>将随机令牌发送到客户端
对于后续请求:
>客户端通过HTTPS在自定义HTTP标头中发送令牌.
>令牌位于数据库中并映射到用户名.如果找到基于允许的角色和允许的操作的访问权限.
>如果未找到,则认为用户未经身份验证,并且必须再次使用登录服务进行身份验证才能获取新令牌.
在服务器端,令牌将以失效日期存储.在每次访问服务时,将更新此日期以创建滑动到期日期.每隔几分钟就会有一个作业删除已过期的令牌,并且检查令牌以查找有效会话的查询只会检查那些未被认为已过期的查询(如果预定的作业因任何原因失败,则会阻止永久会话).
没有必要对数据库中的令牌进行散列和加密 – 除了security through obscurity之外,它没有增加任何实际价值.你可以尽管哈希.这可以防止设法进入会话数据表的攻击者劫持现有用户会话.
标签:java,rest,security,encryption,web-services
来源: https://codeday.me/bug/20190825/1714859.html