登陆认证,权限控制是一个系统必不可少的部分,一个开放访问的系统能否在上线后稳定持续运行其实很大程度上取决于登陆认证和权限控制措施是否到位,不然可能系统刚刚上线就会夭折。
本篇博客回溯登陆认证的变迁历史,阐述session的特点,分析其存在问题,以及token认证的特点,此外阐述了跨站请求伪造攻击CSRF。
1.基于Session的认证简介,基于Token的认证简介;
2.传统Session认证优缺点;
3.token的办法流程,secret是保存在服务器端的,jwt的签发也是在服务端;
4.认识跨站请求伪造(CSRF,Cross-site request forgery);
http请求是无状态的,指的是:http协议协议对于事务处理没有记忆能力,不能保存每次客户端提交的信息,即当服务器返回应答之后,这次事务的所有信息就都丢掉了。如果用户发来一个新的请求,服务器也无法知道它是否与上次的请求有联系。
http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据http协议,我们并不能知道是哪个用户发送的请求,所以为了让我们的应用能识别是哪个用户发出的。
我们只能在服务器存储一份用户登陆的信息,这份登陆信息会在响应时传递给服务器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于sessino认证
但是这种基于session的认证使应用本身很难得扩展,随着不用客户端的增加,独立的服务器已无法承载更多的用户,而这个时候基于session认证应用的问题就会暴露出来
Java网络开发(Session)—— 从http请求 到 cookie 到 session & 用 session控制 删改数据的权限
Session:每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。
应用场景:只适合于单体架构,集群/分布式架构的不合适
扩展性:用户认证之后,服务端做认证记录,如果认证的记录被保存在内存的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,响应的限制了负载均衡器的能力,也意味着限制了应用的扩展性。
CSRF基本原理、GET和POST型CSRF
跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
A并不知道(4)中的请求是C发出的还是B发出的,由于浏览器会自动带上用户C的Cookie,所以A会根据用户的权限处理(4)的请求,这样B就达到了模拟用户操作的目的
从上图能够看出,要完毕一次CSRF攻击,受害者必须依次完毕两个步骤:
其他的攻击
仅仅须要一个HTTP请求。就能够构造一次简单的CSRF。
案例:
<!-- 银行站点A:它以GET请求来完毕银行转账的操作,如:-->
http://www.mybank.com/Transfer.php?toBankId=11&money=1000
<!-- 危急站点B:它里面有一段HTML的代码例如以下:-->
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
首先。你登录了银行站点A,然后訪问危急站点B,这时你会发现你的银行账户少了1000块
为什么会这样呢?原因是银行站点A违反了HTTP规范,使用GET请求更新资源。
在访问危急站点B的之前。你已经登录了银行站点A,而B中的 一个合法的请求,但这里被不法分子利用了)。所以你的浏览器会带上你的银行站点A的Cookie发出Get请求,去获取资源以GET的方式请求第三方资源(这里的第三方就是指银行站点了,原本这是http://www.mybank.com/Transfer.php?toBankId=11&money=1000 ,结果银行站点服务器收到请求后,觉得这是一个更新资源操作(转账操作),所以就立马进行转账操作。
这种类型的CSRF危害没有GET型的大,利用起来通常使用的是一个自动提交的表单
案例:
<form action=http://www.mybank.com/Transfer.php method=POST>
<input type="text" name="toBankId" value="11" />
<input type="text" name="money" value="1000" />
</form>
<script> document.forms[0].submit(); </script>
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。
目前主流的做法是使用Token抵御CSRF攻击。
基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或会话信息。这也就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登陆了,这就为应用的扩展提供了便利。
流程
这个token必须要在每次请求时发送给服务器,它应该保存在请求头中,另外服务器要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了: Access-Control-Allow-Origin:*
(Access-Control-Allow-Origin是HTML5中定义的一种解决资源跨域的策略。他是通过服务器端返回带有Access-Control-Allow-Origin标识的Response header,用来解决资源的跨域权限问题。)
Jwt(Json web token)——从Http协议到session+cookie到Token & Jwt介绍 & Jwt的应用:登陆验证的流程
JSON Web Token(令牌)
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact压缩的 and self-contained自包含的 way for securely transmitting information安全传输 between parties as a JSON object。
This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
- 基于
JSON
格式用于网络传输的令牌。- 紧凑的
Claims
声明格式。Claim
有索赔、声称、要求或者权利要求的含义。
一般用于身份验证和数据信息交换
Json web token(JWT)是为了在网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token(令牌)被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
注意:secret是保存在服务器端的,jwt的签发也是在服务端的,secret就是用来进行jwt的签发和jwt的验证,所以它就是你服务端的私钥,在任何场景都不应该流露出去,一旦客户端得知这个secret,那就意味着客户端可以自我签发jwt了
流程
Token: xxxx.xxxx.xxx
服务端会验证token,如果验证通过就会返回相应的资源,整个流程就是这样
流程
详细流程(时序图)
1.基于Session的认证简介,基于Token的认证简介;
2.传统Session认证优缺点;
3.token的办法流程,secret是保存在服务器端的,jwt的签发也是在服务端;
4.认识跨站请求伪造(CSRF,Cross-site request forgery);