赞
踩
JSON Web 令牌 (JWT) 是一个开放标准,它定义了一种紧凑且自包含的方式,用于将信息作为 JSON 对象安全地在各方之间传输信息。
JWT由三部分组成,中间使用 . 连接,三部分都是由base64编码的,由此来保证url安全的传输。
{
'typ':'jwt',
'alg':'SHA256'
}
使用base64URL编码后:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
{
'id':'10',
'exp':'2301597433'
}
base64URL编码之后为:ewoJJ2lkJzonMTAnLAoJJ2V4cCc6JzIzMDE1OTc0MzMnCn0=
signature = SHA256(base64encode(header) + '.' +
base64encode(payload), 'SEVER_SECRET_KEY')
加密后变成为:05dd35b4d20c95430cd1b63406f861de7e4c1476f9dbffa25f30fe08baf8f530
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ewoJJ2lkJzonMTAnLAoJJ2V4cCc6JzIzMDE1OTc0MzMnCn0=.05dd35b4d20c95430cd1b63406f861de7e4c1476f9dbffa25f30fe08baf8f530
相比于session,它无需保存在服务器,不占服务器内存开销;
无状态、可扩展性性强:
应用程序分布式部署的情况下,客户端的一个令牌可以访问所有的服务器的同时,也避免了服务器之间做session id的多机数据共享。
意思就是
比如有3台机器(A、B、C)组成服务器集群,若session存在机器A上,session只能保存在其中一台服务器,此时你便不能访问机器B、C,因为B、C上没有存放该Session,而使用token就能够验证用户请求合法性,并且我再加几台机器也没事,所以可拓展性好就是这个意思。
由上可知可以支持跨域访问;
性能:
JWT中信息的存储,可以有效的减少服务器查询数据库的次数。
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
public class JWTExample { static String signature = "secritKey"; public static void main(String[] args) { //使用JWT自带的构造器构造一个jwt JwtBuilder builder = Jwts.builder(); String token = builder. //封装header属性(声明类型JWT、声明加密的算法) setHeaderParam("typ","JWT"). setHeaderParam("alg", "HS256") //封装payload里的信息 使用claim方法(封装一些不敏感的信息) .claim("username", "zhangsan") .claim("name", "张三") .claim("age", 18) .claim("sex", "女") //在payLoad中设置一个超时时间 秒 分 时 .setExpiration(new Date(System.currentTimeMillis()+Long.valueOf(1000 * 60 * 60 * 1))) //一个识别id(不重要) .setId("1212121212") //构造signature部分 .signWith(SignatureAlgorithm.HS256, signature) //构造我们的签名 调用compact方法 .compact(); System.out.println(token); } }
//解析token public Jws<Claims> parseJWT(String token,String signature){ //解密 JwtParser parser = Jwts.parser(); Jws<Claims> claimsJws = parser.setSigningKey(signature).parseClaimsJws(token); Claims body = claimsJws.getBody(); //获取name System.out.println(body.get("name")); //获取性别 System.out.println(body.get("sex")); //获取用户名 System.out.println(body.get("username")); //获取姓名 System.out.println(body.get("name")); //获取id System.out.println(body.getId()); //获取有效期-截止时间 System.out.println(body.getSubject()); System.out.println(body.getExpiration()); return claimsJws; }
验证登录状态和接口权限
JWT是 设置了过期时间,若客户端在访问是JWT过期了,该怎么办?
用户重新登录(由前端提醒用户重新登录,或者强制下线,让用户自己重新登录)
续命:
JWT一般存储在redis中,我们可以判断用户使用系统时判断JWT过期时间,然后延长有效期时间
用户鉴权,网络对用户进行鉴权,防止非法用户占用网络资源。
网络鉴权,用户对网络进行鉴权,防止用户接入了非法的网络,被骗取关键信息。
这种双向的认证机制,就是AKA(Authentication and Key Agreement,鉴权和密钥协商)鉴权。
除了AKA鉴权,也可以使用其它鉴权方式。在IMS AKA鉴权广泛实施之前,或在特定的条件下(例如通过固定网络ADSL连接方式接入IMS),可以使用HTTP摘要鉴权等其他鉴权方式。
3G UMTS(Universal Mobile Telecommunication System,通用移动通讯系统)、EPS(Evolved Packet System,演进的分组系统)、IMS(IP Multimedia Subsystem,IP多媒体子系统)网络都采用了AKA双向鉴权机制,鉴权原理也大致相同。而2G网络,只有用户鉴权,无网络鉴权。
移动网络对鉴权时机的要求为:
常用的鉴权有四种:
1、HTTP Basic Authentication
2、session-cookie
3、Token 验证
4、OAuth(开放授权)
这种授权方式是浏览器遵守http协议实现的基本授权方式,HTTP协议进行通信的过程中,HTTP协议定义了基本认证认证允许HTTP服务器对客户端进行用户身份证的方法。
认证过程:
1. 客户端向服务器请求数据,请求的内容可能是一个网页或者是一个ajax异步请求,此时,假设客户端尚未被验证,则客户端提供如下请求至服务器:
Get /index.html HTTP/1.0
Host:www.google.com
2. 服务器向客户端发送验证请求代码401,(WWW-Authenticate: Basic realm=”google.com”这句话是关键,如果没有客户端不会弹出用户名和密码输入界面)服务器返回的数据大抵如下:
HTTP/1.0 401 Unauthorised
Server: SokEvo/1.0
WWW-Authenticate: Basic realm=”google.com”
Content-Type: text/html
Content-Length: xxx
3. 当符合http1.0或1.1规范的客户端(如IE,FIREFOX)收到401返回值时,将自动弹出一个登录窗口,要求用户输入用户名和密码。
4. 用户输入用户名和密码后,将用户名及密码以BASE64加密方式加密,并将密文放入前一条请求信息中,则客户端发送的第一条请求信息则变成如下内容:
Get /index.html HTTP/1.0
Host:www.google.com
Authorization: Basic d2FuZzp3YW5n
注:d2FuZzp3YW5n表示加密后的用户名及密码(用户名:密码 然后通过base64加密,加密过程是浏览器默认的行为,不需要我们人为加密,我们只需要输入用户名密码即可)
5. 服务器收到上述请求信息后,将Authorization字段后的用户信息取出、解密,将解密后的用户名及密码与用户数据库进行比较验证,如用户名及密码正确,服务器则根据请求,将所请求资源发送给客户端。
效果:
客户端未未认证的时候,会弹出用户名密码输入框,这个时候请求时属于pending状态,这个时候其实服务当用户输入用户名密码的时候客户端会再次发送带Authentication头的请求。
HTTP Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。
(一)Cookie主要用于以下三个方面:
(二) 认证过程
1、服务器在接受客户端首次访问时在服务器端创建seesion,然后保存seesion(我们可以将seesion保存在内存中,也可以保存在redis中,推荐使用后者),然后给这个session生成一个唯一的标识字符串,然后在响应头中种下这个唯一标识字符串。
2、签名。这一步只是对sid进行加密处理,服务端会根据这个secret密钥进行解密。(非必需步骤)
3、浏览器中收到请求响应的时候会解析响应头,然后将sid保存在本地cookie中,浏览器在下次http请求de 请求头中会带上该域名下的cookie信息。
4、服务器在接受客户端请求时会去解析请求头cookie中的sid,然后根据这个sid去找服务器端保存的该客户端的session,然后判断该请求是否合法。
5、一旦用户登出,服务端和客户端同时销毁该会话在后续请求中,服务器会根据数据库验证会话id,如果验证通过,则继续处理;
(一) 认证过程
(二) cookie与taken性能对比
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。
我们常见的提供OAuth认证服务的厂商有支付宝,QQ,微信。
OAuth协议又有1.0和2.0两个版本。相比较1.0版,2.0版整个授权验证流程更简单更安全,也是目前最主要的用户身份验证和授权方式。
典型案例
果一个用户拥有两项服务:一项服务是图片在线存储服务A,另一个是图片在线打印服务B。由于服务A与服务B是由两家不同的服务提供商提供的,所以用户在这两家服务提供商的网站上各自注册了用户,假设这两个用户名各不相同,密码也各不相同。
当用户要使用服务B打印存储在服务A上的图片时,用户该如何处理?
方法一:
用户可能先将待打印的图片从服务A上下载下来并上传到服务B上打印,这种方式安全但处理比较繁琐,效率低下;
方法二:
用户将在服务A上注册的用户名与密码提供给服务B,服务B使用用户的帐号再去服务A处下载待打印的图片,这种方式效率是提高了,但是安全性大大降低了,服务B可以使用用户的用户名与密码去服务A上查看甚至篡改用户的资源。
方法三:
当服务B(打印服务)要访问用户的服务A(图片服务)时,通过OAUTH机制,服务B向服务A请求未经用户授权的RequestToken后,服务A将引导用户在服务A的网站上登录,并询问用户是否将图片服务授权给服务B。用户同意后,服务B就可以访问用户在服务A上的图片服务。整个过程服务B没有触及到用户在服务A的帐号信息。
OAuth相关术语
在认证和授权的过程中涉及的三方包括:
服务提供方(ServiceProvider),用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。
用户(User),存放在服务提供方的受保护的资源的拥有者
- 服务提供方(ServiceProvider),用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。
- 用户(User),存放在服务提供方的受保护的资源的拥有者
客户端(Consumer),要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站也可以是桌面或移动应用程序。在认证过程之前,客户端要向服务提供者申请客户端标识。
OAuth相关的三个URL:
- RequestToken URL:获取未授权的RequestToken服务地址;
- UserAuthorization URL:获取用户授权的RequestToken服务地址;
- AccessToken URL:用授权的RequestToken换取AccessToken的服务地址。
OAuth认证和授权过程
- 1、客户端(第三方软件)向OAUTH服务提供商请求未授权的RequestToken。即RequestToken URL发起请求;
-
- 2、OAUTH服务提供商同意使用者的请求,并向其颁发未经用户授权的oauth_token与对应的oauth_token_secret,并返回给使用者;
-
- 3、使用者向OAUTH服务提供商请求用户授权的RequestToken。即向UserAuthorization URL发起请求并在请求中携带上一步服务提供商颁发的未授权的token与其密钥;
-
- 4、OAUTH服务提供商通过网页要求用户登录并引导用户完成授权;
-
- 5、RequestToken授权后,使用者将向AccessToken URL发起请求,将上步授权RequestToken换取成AccessToken。请求的参数见上图,这个比第一步多了一个参数就是RequestToken;
-
- 6、OAUTH服务提供商同意使用者的请求,并向其颁发AccessToken与对应的密钥,并返回给使用者;
-
- 7、使用者以后就可以使用上步返回的AccessToken访问用户授权的资源。
简单整理就三个步骤
1、获取未授权的RequestToken
2、获取用户授权的RequestToken
3、用授权的RequestToken换取AccessToken
TODO
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。