四种常用鉴权方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四种常用鉴权方式相关的知识,希望对你有一定的参考价值。

参考技术A

由于http 协议是一种无状态的协议,服务器端并不知道客户端的那一头是谁在请求服务器。而且服务器上的资源不一定是对所有人开放,所以需要进行用户对登录鉴权。目前,我们在开发中主要使用过4 种鉴权方式。

这种授权方式是浏览器遵守http协议实现的基本授权方式。

优点  基本上所有流行的网页浏览器都支持基本认证。基本认证很少在可公开访问的互联网网站上使用,有时候会在小的私有系统中使用(如路由器网页管理接口)。后来的机制HTTP摘要认证是为替代基本认证而开发的,允许密钥以相对安全的方式在不安全的通道上传输。 程序员和系统管理员有时会在可信网络环境中使用基本认证,使用Telnet或其他明文网络协议工具手动地测试Web服务器。这是一个麻烦的过程,但是网络上传输的内容是人可读的,以便进行诊断。

缺点  虽然基本认证非常容易实现,但该方案创建在以下的假设的基础上,即:客户端和服务器主机之间的连接是安全可信的。特别是,如果没有使用SSL/TLS这样的传输层安全的协议,那么以明文传输的密钥和口令很容易被拦截。该方案也同样没有对服务器返回的信息提供保护。 现存的浏览器保存认证信息直到标签页或浏览器被关闭,或者用户清除历史记录。HTTP没有为服务器提供一种方法指示客户端丢弃这些被缓存的密钥。这意味着服务器端在用户不关闭浏览器的情况下,并没有一种有效的方法来让用户注销。

优缺点

session-cookie的缺点
(1)认证方式局限于在浏览器中使用, cookie 是浏览器端的机制,如果在app端就无法使用 cookie 。
(2)为了满足全局一致性,我们最好把 session 存储在 redis 中做持久化,而在分布式环境下,我们可能需要在每个服务器上都备份,占用了大量的存储空间。
(3)在不是 Https 协议下使用 cookie ,容易受到 CSRF 跨站点请求伪造攻击。

token 是一个令牌,当浏览器第一次访问服务端时会签发一张令牌,之后浏览器每次携带这张令牌访问服务端就会认证该令牌是否有效,只要服务端可以解密该令牌,就说明请求是合法的。一般 token 由用户信息、时间戳和由 hash 算法加密的签名构成。

优点
(1) token 认证不局限于 cookie ,这样就使得这种认证方式可以支持多种客户端,而不仅是浏览器。且不受同源策略的影响。
(2)不使用 cookie 就可以规避CSRF攻击。
(3) token 不需要存储, token 中已包含了用户信息,服务器端变成无状态,服务器端只需要根据定义的规则校验这个 token 是否合法就行。这也使得 token 的可扩展性更强。

缺点
(1)加密解密消耗使得 token 认证比 session-cookie 更消耗性能。
(2) token 比 sessionId 大,更占带宽。

由于app没有浏览器无法存储cookie,故出现了OAuth,且允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAuth是安全的。

基于token机制鉴权架构

参考技术A

常见的鉴权方式有两种,一种是基于session,另一种是基于token方式的鉴权,我们来浅谈一下两种 鉴权方式的区别。

session

token

业界常用的授权标准有两种,一种是使用auth2,这种方式更适合于类似第三方授权登录,比如微信、微博、QQ信任登录业务。另一种是oauth,即第三方无需知道用户和密码就可以申请获得该资源的授权,更适用于对用户的权限校验并分配访问权限,比如常见的登录后分配可见资源(按钮、菜单等)类型网站。

Javashop电商系统 采用的是oauth方式的鉴权标准。我们以系统的应用为例来介绍oauth的方案。

1. 登录

服务端校验密码,成功后返回access_token和refresh_token,客户端记录上述token。

2. 访问API

在访问API之前解析access_token,并且查看是否过期,如果不过 期则请求API,如果过期,则要刷新令牌,在请求API。

3. 刷新token

携带有效期的refresh_token换回有效token,如果refresh_token过期,则需要用户重新登录。

4. 注销

请求注销api,服务器端和客户端应同时删除token的存储。

1. 客户端请求API

携带access_token信息,如果生成环境不会直接携带access_token,会使用加密后的签名校验。祥见以下防重放机制。

2. 获取token

根据环境不同而有不同的获取token方式。

3. 解析token

通过JWT工具将token解析。

4. 由redis读取token

根据uid拼接key读取access_token, 如果不存在这个用户的token说明已经登出。

5. 验证token

判断次token是否属于此uid,判断token是否过期,如果过期则进行以下刷新token的流程。

6. 注入权限

如果token验证成功,根据user信息生成权限注入到spring安全上下文中。

1. 客户端请求API

携带refresh_token,如果是生产环境不会直接携带refresh_token信息,详见以下防重放攻击。

2. 获取token

根据环境不同而有不同的获取token方式。

3. 解析token

通过JWT工具将token解析。

4. token读取

根据uid拼接key读取出access_token,如果不存在这个用户的token说明用户已经登出。

5. 验证token

判断此token是否属于此uid,判断token是否已经过期,如果过期,则返回refresh_token过期错误,此时用户需要重新登录。

6. 刷新token

如果refresh_token 验证成功,则重新生成access_token和refresh_token,上述有效期以当前时间向后计算,替换此用户在redis中的token,并将token返回给客户端。

一、 参数的读取

1. 在生产环境时,不能直接传递token,而是要传递签名数据,服务器端验签后由Redis中获取签名。

2. 如果是非生产环境,直接由header中读取token。

二、 生产环境传递如下参数

memberid (用户id)

nonce(随机字串,6位)

timestamp(当前时间戳,到秒)

sign= md5( uid+ nonce + timestamp +token )

三、 验证逻辑

1. 验证时间戳

判断时间戳是否起过60s,大于60s则判别为重放功击。

2. 验证nonce

首先验证nonce在 reids中是否存在,如果存在,则判别为重放功击,否则将nonce记录在redis中(key为:"nonce"+uid+"_"+nonce),失效时间为60s。

3. 验证sign

md5( uid+ nonce + timestamp +token ) 验证是签名是否通过。

4. 验证token

通过uid拿到token ,验证逻辑同验权流程。

当然在不同的业务场景下实现方案是多种多样的,仅以此方案抛转引玉,供大家参考。

以上是关于四种常用鉴权方式的主要内容,如果未能解决你的问题,请参考以下文章

ArrayList去重常用的四种方式及性能对比(JMH性能分析)

学习笔记——原生js中常用的四种循环方式

四种常用的post数据提交方式

java读取配置文件常用的四种方式

C#播放背景音乐常用的四种方式

必学必备的几种接口鉴权方式