Skip to content

Commit

Permalink
Merge branch 'Snailclimb:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
TommyMerlin committed Jun 15, 2021
2 parents 2cba4f0 + 1bf506b commit cfc8c9f
Show file tree
Hide file tree
Showing 12 changed files with 28 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现,

JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。 JDK1.8 以后的 `HashMap` 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。

`HashMap` 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。并且, `HashMap` 总是使用 2 的幂作为哈希表的大小
`HashMap` 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。并且, `HashMap` 总是使用 2 的幂作为哈希表的大小

## 底层数据结构分析

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

这两个一般在我们的系统中被结合在一起使用,目的就是为了保护我们系统的安全性。

## RBAC 模型介绍一下
## RBAC 模型了解吗

系统权限控制最常采用的访问控制模型就是 **RBAC 模型**

Expand Down Expand Up @@ -129,22 +129,18 @@ public String readAllCookies(HttpServletRequest request) {

关于这种认证方式更详细的过程如下:

![Session Based Authentication flow](./images/basis-of-authority-certification/Session-Based-Authentication-flow.png)
![](./images/basis-of-authority-certification/session-cookie.png)

1. 用户向服务器发送用户名和密码用于登陆系统
2. 服务器验证通过后,服务器为用户创建一个 `Session`,并将 `Session` 信息存储 起来
1. 用户向服务器发送用户名、密码、验证码用于登陆系统
2. 服务器验证通过后,服务器为用户创建一个 `Session`,并将 `Session` 信息存储起来
3. 服务器向用户返回一个 `SessionID`,写入用户的 `Cookie`
4. 当用户保持登录状态时,`Cookie` 将与每个后续请求一起被发送出去。
5. 服务器可以将存储在 `Cookie` 上的 `SessionID` 与存储在内存中或者数据库中的 `Session` 信息进行比较,以验证用户的身份,返回给用户客户端响应信息的时候会附带用户当前的状态。

使用 `Session` 的时候需要注意下面几个点:

1. 依赖 `Session` 的关键业务一定要确保客户端开启了 `Cookie`
2. 注意 `Session` 的过期时间

画了个图简单总结了一下 `Session` 认证涉及的一些东西。

![](./images/basis-of-authority-certification/Session-cookie-intro.jpeg)
2. 注意 `Session` 的过期时间。

另外,Spring Session 提供了一种跨多个应用程序或实例管理用户会话信息的机制。如果想详细了解可以查看下面几篇很不错的文章:

Expand Down Expand Up @@ -188,21 +184,23 @@ Session-Cookie 方案在单体环境是一个非常好的身份认证方案。

`Session` 认证中 `Cookie` 中的 `SessionId` 是由浏览器发送到服务端的,借助这个特性,攻击者就可以通过让用户误点攻击链接,达到攻击效果。

但是,我们使用 `Token` 的话就不会存在这个问题,在我们登录成功获得 `Token` 之后,一般会选择存放在 local storage 中。然后我们在前端通过某些方式会给每个发到后端的请求加上这个 `Token`,这样就不会出现 CSRF 漏洞的问题。因为,即使有个你点击了非法链接发送了请求到服务端,这个非法请求是不会携带 `Token` 的,所以这个请求将是非法的。
但是,我们使用 `Token` 的话就不会存在这个问题,在我们登录成功获得 `Token` 之后,一般会选择存放在 `localStorage` (浏览器本地存储)中。然后我们在前端通过某些方式会给每个发到后端的请求加上这个 `Token`,这样就不会出现 CSRF 漏洞的问题。因为,即使有个你点击了非法链接发送了请求到服务端,这个非法请求是不会携带 `Token` 的,所以这个请求将是非法的。

![](https://img-blog.csdnimg.cn/20210615161108272.png)

需要注意的是不论是 Cookie 还是 Token 都无法避免 **跨站脚本攻击(Cross Site Scripting)XSS**
需要注意的是不论是 `Cookie` 还是 `Token` 都无法避免 **跨站脚本攻击(Cross Site Scripting)XSS**

> 跨站脚本攻击(Cross Site Scripting)缩写为 CSS 但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为 XSS。
XSS 中攻击者会用各种方式将恶意代码注入到其他用户的页面中。就可以通过脚本盗用信息比如 cookie
XSS 中攻击者会用各种方式将恶意代码注入到其他用户的页面中。就可以通过脚本盗用信息比如 `Cookie`

推荐阅读:[如何防止 CSRF 攻击?—美团技术团队](https://tech.meituan.com/2018/10/11/fe-security-csrf.html)

## 什么是 Token?什么是 JWT?

我们在上一个问题中探讨了使用 Session 来鉴别用户的身份,并且给出了几个 Spring Session 的案例分享。 我们知道 Session 信息需要保存一份在服务器端。这种方式会带来一些麻烦,比如需要我们保证保存 Session 信息服务器的可用性、不适合移动端(依赖 Cookie)等等。
我们在前面的问题中探讨了使用 `Session` 来鉴别用户的身份,并且给出了几个 Spring Session 的案例分享。 我们知道 `Session` 信息需要保存一份在服务器端。这种方式会带来一些麻烦,比如需要我们保证保存 `Session` 信息服务器的可用性、不适合移动端(依赖 `Cookie`)等等。

有没有一种不需要自己存放 Session 信息就能实现身份验证的方式呢?使用 Token 即可!JWT (JSON Web Token) 就是这种方式的实现,通过这种方式服务器端就不需要保存 Session 数据了,只用在客户端保存服务端返回给客户的 Token 就可以了,扩展性得到提升。
有没有一种不需要自己存放 `Session` 信息就能实现身份验证的方式呢?使用 `Token` 即可!**JWT** (JSON Web Token) 就是这种方式的实现,通过这种方式服务器端就不需要保存 `Session` 数据了,只用在客户端保存服务端返回给客户的 `Token` 就可以了,扩展性得到提升。

**JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的,因此接收者便可以验证它的真实性。**

Expand All @@ -212,27 +210,26 @@ XSS 中攻击者会用各种方式将恶意代码注入到其他用户的页面
JWT 由 3 部分构成:

1. **Header** : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
1. **Header** : 描述 JWT 的元数据,定义了生成签名的算法以及 `Token` 的类型。
2. **Payload** : 用来存放实际需要传递的数据
3. **Signature(签名)** :服务器通过`Payload``Header`和一个密钥(`secret`)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。
3. **Signature(签名)** :服务器通过`Payload``Header`和一个密钥(`secret`)使用 `Header` 里面指定的签名算法(默认是 HMAC SHA256)生成。

## 如何基于 Token 进行身份验证?

在基于 Token 进行身份验证的的应用程序中,服务器通过`Payload``Header`和一个密钥(`secret`)创建令牌(`Token`)并将 `Token` 发送给客户端,客户端将 `Token` 保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization 字段中:`Authorization: Bearer Token`

![Token Based Authentication flow](./images/basis-of-authority-certification/Token-Based-Authentication.png)
![jwt](./images/basis-of-authority-certification/jwt.png)

1. 用户向服务器发送用户名和密码用于登陆系统。
2. 身份验证服务响应并返回了签名的 JWT,上面包含了用户是谁的内容。
3. 用户以后每次向后端发请求都在 Header 中带上 JWT。
3. 用户以后每次向后端发请求都在 `Header` 中带上 JWT。
4. 服务端检查 JWT 并从中获取用户相关信息。

推荐阅读:
## 什么是 SSO?

SSO(Single Sign On)即单点登录说的是用户登陆多个子系统的其中一个就有权访问与其相关的其他系统。举个例子我们在登陆了京东金融之后,我们同时也成功登陆京东的京东超市、京东国际、京东生鲜等子系统。

- [JWT (JSON Web Tokens) Are Better Than Session Cookies](https://dzone.com/articles/jwtjson-web-Tokens-are-better-than-Session-cookies)
- [JSON Web Tokens (JWT) 与 Sessions](https://juejin.im/entry/577b7b56a3413100618c2938)
- [JSON Web Token 入门教程](https://www.ruanyifeng.com/blog/2018/07/json_web_Token-tutorial.html)
- [彻底理解 Cookie,Session,Token](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485603&idx=1&sn=c8d324f44d6102e7b44554733da10bb7&chksm=cea24768f9d5ce7efe7291ddabce02b68db34073c7e7d9a7dc9a7f01c5a80cebe33ac75248df&Token=844918801&lang=zh_CN#rd)
![sso](./images/basis-of-authority-certification/sso.png)

## 什么是 OAuth 2.0?

Expand All @@ -248,19 +245,13 @@ OAuth 2.0 比较常用的场景就是第三方登录,当你的网站接入了

![](./images/basis-of-authority-certification/微信支付-fnglfdlgdfj.png)

下图是 [Slack OAuth 2.0 第三方登录](https://api.slack.com/legacy/oauth)的示意图:

![](https://img-blog.csdnimg.cn/20210615151716340.png)

**推荐阅读:**

- [OAuth 2.0 的一个简单解释](http://www.ruanyifeng.com/blog/2019/04/oauth_design.html)
- [10 分钟理解什么是 OAuth 2.0 协议](https://deepzz.com/post/what-is-oauth2-protocol.html)
- [OAuth 2.0 的四种方式](http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html)
- [GitHub OAuth 第三方登录示例教程](http://www.ruanyifeng.com/blog/2019/04/github-oauth.html)

## 什么是 SSO?

SSO(Single Sign On)即单点登录说的是用户登陆多个子系统的其中一个就有权访问与其相关的其他系统。举个例子我们在登陆了京东金融之后,我们同时也成功登陆京东的京东超市、京东家电等子系统。

## 参考

- https://medium.com/@sherryhsu/Session-vs-Token-based-authentication-11a6c5ac45e4
- https://www.varonis.com/blog/what-is-oauth/
- https://tools.ietf.org/html/rfc6749
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile host="Electron" modified="2021-06-15T07:51:52.006Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="BlT26OI0w3JnmsRQ2GOB" version="13.4.5" type="device"><diagram id="Gv1XkoxmDoOVkgf1aGpN" name="Page-1">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</diagram></mxfile>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading

0 comments on commit cfc8c9f

Please sign in to comment.