Authentication:
http是一种无状态的协议, 浏览器和web server可以通过cookie来识别身份。
应用程序一般不会使用cookie识别身份,通常是把 "用户名+密码"用BASE64编码放在请求头的Authorization中发送给服务端, 这种方式叫HTTP基本认证(Basic Authentication)。
1.client发送http request到web server 。
2.request中没有包含Authorization头, web server返回一个401 Unauthozied 给client,在response的头WWW-Authenticate中添加信息。
3.client把username和passwd用编码(或者加密)后,放在Authorization头中发送给web server。
4.web server将Authorization头中的username和passwd解码(或解密)进行验证, 如果验证通过,将根据请求发送资源给客户端。
这样的请求在网络上用HTTP传输是很不安全的。 一般会用HTTPS传输,。
https在http基础上面添加了ssl安全证书,请求并发一旦上去的话耗时要比http多出很多,缓存没有http好。有时https也是有一定的缺点,https真是请求响应内容进行加密的,但HTTPS协议的加密范围有限,ssl证书信用链体系并不绝对安全,在可以控制CA根证书的情况下,中间人攻击一样可行。即使https协议在黑客攻击、ddos/cc、服务器劫持等方面起不到什么作用。
最好的方式就是内容https加密+身份验证机制。特别是在防爬虫、突破权限获取数据效果最为明显
OAuth:
OAuth对于Http来说,放在Authorization头中的不是用username和passwd,而是一个token。
OAuth是一个开放标准,提供了一种简单和标准的安全授权方法,允许用户无需将某个网站的用户名密码提供给第三方应用就可以让该第三方应用访问该用户在某网站上的某些特定信息(如简单的个人信息)。
我们通常在网站上注册的时候,要填写邮箱user信息很多东西balabala...,如果使用oauth协议会省略这个比较麻烦的步骤。网站后台在处理登陆的时候,调用了oauth协议,用户在登陆的时候可以使用第三方账号登陆。例如:在我们访问博客or论坛想要发帖或者下载东西时,都需要在登录网站后才可以操作。我们经常在网站登陆页面上,显示可以选择QQ/微信/微博登陆,优化了用户对页面的体验。这就是使用了第三方的登陆,oauth第三方协议成了现在较为流行的一种登陆方式。
现在一般用的是OAuth2.0
OAuth2.0协议交互流程
+--------+ +---------------+| |--(A)- Authorization Request ->| Resource || | | Owner || |<-(B)-- Authorization Grant ---| || | +---------------+| || | +---------------+| |--(C)-- Authorization Grant -->| Authorization || Client | | Server || |<-(D)----- Access Token -------| || | +---------------+| || | +---------------+| |--(E)----- Access Token ------>| Resource || | | Server || |<-(F)--- Protected Resource ---| |+--------+ +---------------+
Token为获取信息的凭证,如上图的Access Token,关于Token的具体使用有相应的RFC文件指导
OAuth1.0和OAuth2.0 官方RFC文档:
https://tools.ietf.org/html/rfc5849
https://tools.ietf.org/html/rfc6750
Token的类型可分为两种:
1.Bearer 包含一个简单的Token字符串.
2.MAC 由消息授权码(Message Authentication Code)和Token组成
Authorization: Bearer sF_6.B7f-8.9xmP
Authorization: MAC id="t67vi01hd3",nonce="849662:fs873ka",mac="NsdHsdndKBkjfKfhKJN="
Token的认证请求的方式有三种,客户端可以选择任意一种:
1.放在URI
GET /index.html?access_token=sF_6.B7f-8.9xmP
Host: test.com
2.放在请求头
GET /index.html HTTP/1.1
Host: test.com
Authorization: Bearer sF_6.B7f-8.9xmP
3.放在请求体
POST /index.html HTTP/1.1
Host: test.com
Content-Type: application/x-www-form-urlencoded
access_token=Bearer sF_6.B7f-8.9xmP
Spring Security OAuth框架学习:
https://spring.io/projects/spring-security-oauth
JWT:
JWT: 是一个开放的标准,规定了一种Token实现方式,以JSON为格式。
官方RFC文档:
https://tools.ietf.org/html/rfc7519
原理:
1.server给client分配一个加密的token。
2.client保存这个token,以后的每个请求client都会发送这个token。
3.server通过token判断是否是鉴权过的用户,并返回请求的响应数据。
可以通过url/请求头/post参数发送,数据量小传输速度快。
payload中包含了所有用户所需要的信息,由于JWT是自包含的避免了多次查询数据库。
JWT结构分为三部分:
Header: 存放Token类型和加密算法。
Payload: 用户身份信息。
Signature: 签名是将前面的Header,Payload信息以及一个密钥组合起来并使用Header中的算法进行加密。
算法(base64UrlEncode(header) + "." + base64UrlEncode(payload), 密钥)
Signature用于验证消息的发送者以及消息内容有没有经过篡改。如果黑客获取到了payload中的用户信息,并进行了篡改,那么经过Base64编码后也会发生变化,而签名是根据Header和Payload共同决定的,签名也会不一样,服务器就会判断出不一致。
完整的JWT格式,它拼接了之前的Header, Payload以及秘钥签名:
1)用户在client输入用户名和密码登录。
2)server认证通过后,返回给用户一个JWT。
3)client只需在本地保存该token,通常使用local storage也可以使用cookie。
4)当用户下次访问时,在Authorization头部使用Bearer模式添加JWT,格式Authentication:
Bearer <token>。
5)server检查请求头Authentication中的JWT,如果合法则允许用户的行为。