关于java:认证授权基础

5次阅读

共计 6125 个字符,预计需要花费 16 分钟才能阅读完成。

1. 认证 (Authentication) 和受权 (Authorization)的区别是什么?

这是一个绝大多数人都会混同的问题。首先先从读音上来意识这两个名词,很多人都会把它俩的读音搞混,所以我倡议你先先去查一查这两个单词到底该怎么读,他们的具体含意是什么。

说简略点就是:

认证 (Authentication): 你是谁。

受权 (Authorization): 你有权限干什么。

略微正式点(啰嗦点)的说法就是:

  • Authentication(认证) 是验证您的身份的凭据(例如用户名 / 用户 ID 和明码),通过这个凭据,零碎得以晓得你就是你,也就是说零碎存在你这个用户。所以,Authentication 被称为身份 / 用户验证。
  • Authorization(受权) 产生在 Authentication(认证) 之后。受权嘛,光看意思大家应该就明确,它次要主持咱们拜访零碎的权限。比方有些特定资源只能具备特定权限的人才能拜访比方 admin,有些对系统资源操作比方删除、增加、更新只能特定人才具备。

这两个个别在咱们的零碎中被联合在一起应用,目标就是为了爱护咱们零碎的安全性。

2. 什么是 Cookie ? Cookie 的作用是什么? 如何在服务端应用 Cookie ?

2.1 什么是 Cookie ? Cookie 的作用是什么?

Cookie 和 Session 都是用来跟踪浏览器用户身份的会话形式,然而两者的利用场景不太一样。

维基百科是这样定义 Cookie 的:Cookies 是某些网站为了分别用户身份而贮存在用户本地终端上的数据(通常通过加密)。简略来说:Cookie 寄存在客户端,个别用来保留用户信息

上面是 Cookie 的一些利用案例:

  1. 咱们在 Cookie 中保留曾经登录过的用户信息,下次访问网站的时候页面能够主动帮你登录的一些根本信息给填了。除此之外,Cookie 还能保留用户首选项,主题和其余设置信息。
  2. 应用 Cookie 保留 session 或者 token,向后端发送申请的时候带上 Cookie,这样后端就能取到 session 或者 token 了。这样就能记录用户以后的状态了,因为 HTTP 协定是无状态的。
  3. Cookie 还能够用来记录和剖析用户行为。举个简略的例子你在网上购物的时候,因为 HTTP 协定是没有状态的,如果服务器想要获取你在某个页面的停留状态或者看了哪些商品,一种罕用的实现形式就是将这些信息寄存在 Cookie

2.2 如何在服务端应用 Cookie 呢?

这部分内容参考:https://attacomsian.com/blog/cookies-spring-boot,更多如何在 Spring Boot 中应用 Cookie 的内容能够查看这篇文章。

1)设置 cookie 返回给客户端

@GetMapping("/change-username")
public String setCookie(HttpServletResponse response) {
// 创立一个 cookie
Cookie cookie = new Cookie("username", "Jovan");
// 设置 cookie 过期工夫
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
// 增加到 response 中
response.addCookie(cookie);

return "Username is changed!";
}

2) 应用 Spring 框架提供的 @CookieValue 注解获取特定的 cookie 的值

@GetMapping("/")
public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") String username) {return "Hey! My username is" + username;}

3) 读取所有的 Cookie 值

@GetMapping("/all-cookies")
public String readAllCookies(HttpServletRequest request) {Cookie[] cookies = request.getCookies();
if (cookies != null) {return Arrays.stream(cookies)
.map(c -> c.getName() + "=" + c.getValue()).collect(Collectors.joining(","));
}

return "No cookies";
}

3. Cookie 和 Session 有什么区别?如何应用 Session 进行身份验证?

Session 的次要作用就是通过服务端记录用户的状态。 典型的场景是购物车,当你要增加商品到购物车的时候,零碎不晓得是哪个用户操作的,因为 HTTP 协定是无状态的。服务端给特定的用户创立特定的 Session 之后就能够标识这个用户并且跟踪这个用户了。

Cookie 数据保留在客户端(浏览器端),Session 数据保留在服务器端。相对来说 Session 安全性更高。如果应用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密而后应用到的时候再去服务器端解密。

那么,如何应用 Session 进行身份验证?

很多时候咱们都是通过 SessionID 来实现特定的用户,SessionID 个别会抉择寄存在 Redis 中。举个例子:用户胜利登陆零碎,而后返回给客户端具备 SessionID 的 Cookie,当用户向后端发动申请的时候会把 SessionID 带上,这样后端就晓得你的身份状态了。对于这种认证形式更具体的过程如下:

  1. 用户向服务器发送用户名和明码用于登陆零碎。
  2. 服务器验证通过后,服务器为用户创立一个 Session,并将 Session 信息存储 起来。
  3. 服务器向用户返回一个 SessionID,写入用户的 Cookie。
  4. 当用户放弃登录状态时,Cookie 将与每个后续申请一起被发送进来。
  5. 服务器能够将存储在 Cookie 上的 Session ID 与存储在内存中或者数据库中的 Session 信息进行比拟,以验证用户的身份,返回给用户客户端响应信息的时候会附带用户以后的状态。

应用 Session 的时候须要留神上面几个点:

  1. 依赖 Session 的要害业务肯定要确保客户端开启了 Cookie。
  2. 留神 Session 的过期工夫

花了个图简略总结了一下 Session 认证波及的一些货色。

另外,Spring Session 提供了一种跨多个应用程序或实例治理用户会话信息的机制。如果想具体理解能够查看上面几篇很不错的文章:

  • Getting Started with Spring Session
  • Guide to Spring Session
  • Sticky Sessions with Spring Session & Redis

4. 如果没有 Cookie 的话 Session 还能用吗?

这是一道经典的面试题!

个别是通过 Cookie 来保留 SessionID,如果你应用了 Cookie 保留 SessionID 的计划的话,如果客户端禁用了 Cookie,那么 Session 就无奈失常工作。

然而,并不是没有 Cookie 之后就不能用 Session 了,比方你能够将 SessionID 放在申请的 url 外面https://javaguide.cn/?session_id=xxx。这种计划的话可行,然而安全性和用户体验感升高。当然,为了你也能够对 SessionID 进行一次加密之后再传入后端。

5. 为什么 Cookie 无奈避免 CSRF 攻打,而 token 能够?

CSRF(Cross Site Request Forgery)个别被翻译为 跨站申请伪造 。那么什么是 跨站申请伪造 呢?说简略用你的身份去发送一些对你不敌对的申请。举个简略的例子:

小壮登录了某网上银行,他来到了网上银行的帖子区,看到一个帖子上面有一个链接写着“迷信理财,年盈利率过万”,小壮好奇的点开了这个链接,后果发现自己的账户少了 10000 元。这是这么回事呢?原来黑客在链接中藏了一个申请,这个申请间接利用小壮的身份给银行发送了一个转账申请, 也就是通过你的 Cookie 向银行发出请求。

<a src="http://www.mybank.com/Transfer?bankId=11&money=10000"> 迷信理财,年盈利率过万 </a>

下面也提到过,进行 Session 认证的时候,咱们个别应用 Cookie 来存储 SessionId, 当咱们登陆后后端生成一个 SessionId 放在 Cookie 中返回给客户端,服务端通过 Redis 或者其余存储工具记录保留着这个 Sessionid,客户端登录当前每次申请都会带上这个 SessionId,服务端通过这个 SessionId 来标示你这个人。如果他人通过 cookie 拿到了 SessionId 后就能够代替你的身份拜访零碎了。

Session 认证中 Cookie 中的 SessionId 是由浏览器发送到服务端的,借助这个个性,攻击者就能够通过让用户正点攻打链接,达到攻打成果。

然而,咱们应用 token 的话就不会存在这个问题,在咱们登录胜利取得 token 之后,个别会抉择寄存在 local storage 中。而后咱们在前端通过某些形式会给每个发到后端的申请加上这个 token, 这样就不会呈现 CSRF 破绽的问题。因为,即便有个你点击了非法链接发送了申请到服务端,这个非法申请是不会携带 token 的,所以这个申请将是非法的。

须要留神的是不论是 Cookie 还是 token 都无奈防止跨站脚本攻打(Cross Site Scripting)XSS。

跨站脚本攻打(Cross Site Scripting)缩写为 CSS 但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混同。因而,有人将跨站脚本攻打缩写为 XSS。

XSS 中攻击者会用各种形式将恶意代码注入到其余用户的页面中。就能够通过脚本盗用信息比方 cookie。

举荐浏览:如何避免 CSRF 攻打?—美团技术团队

6. 什么是 Token? 什么是 JWT? 如何基于 Token 进行身份验证?

咱们在上一个问题中探讨了应用 Session 来甄别用户的身份,并且给出了几个 Spring Session 的案例分享。咱们晓得 Session 信息须要保留一份在服务器端。这种形式会带来一些麻烦,比方须要咱们保障保留 Session 信息服务器的可用性、不适宜挪动端(依赖 Cookie)等等。

有没有一种不须要本人寄存 Session 信息就能实现身份验证的形式呢?应用 Token 即可!JWT(JSON Web Token)就是这种形式的实现,通过这种形式服务器端就不须要保留 Session 数据了,只用在客户端保留服务端返回给客户的 Token 就能够了,扩展性失去晋升。

JWT 实质上就一段签名的 JSON 格局的数据。因为它是带有签名的,因而接收者便能够验证它的真实性。

上面是 RFC 7519 对 JWT 做的较为正式的定义。

JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted. ——JSON Web Token (JWT)

JWT 由 3 局部形成:

  1. Header : 形容 JWT 的元数据。定义了生成签名的算法以及 Token 的类型。
  2. Payload(负载): 用来寄存理论须要传递的数据
  3. Signature(签名):服务器通过 PayloadHeader 和一个密钥 (secret) 应用 Header 外面指定的签名算法(默认是 HMAC SHA256)生成。

在基于 Token 进行身份验证的的应用程序中,服务器通过 PayloadHeader 和一个密钥 (secret) 创立令牌(Token)并将 Token 发送给客户端,客户端将 Token 保留在 Cookie 或者 localStorage 外面,当前客户端收回的所有申请都会携带这个令牌。你能够把它放在 Cookie 外面主动发送,然而这样不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization 字段中: Authorization: Bearer Token

  1. 用户向服务器发送用户名和明码用于登陆零碎。
  2. 身份验证服务响应并返回了签名的 JWT,下面蕴含了用户是谁的内容。
  3. 用户当前每次向后端发申请都在 Header 中带上 JWT。
  4. 服务端查看 JWT 并从中获取用户相干信息。

举荐浏览:

  • JWT (JSON Web Tokens) Are Better Than Session Cookies
  • JSON Web Tokens (JWT) 与 Sessions
  • JSON Web Token 入门教程
  • 彻底了解 Cookie,Session,Token

7 什么是 OAuth 2.0?

OAuth 是一个行业的规范受权协定,次要用来受权第三方利用获取无限的权限。而 OAuth 2.0 是对 OAuth 1.0 的齐全从新设计,OAuth 2.0 更快,更容易实现,OAuth 1.0 曾经被废除。详情请见:rfc6749。

实际上它就是一种受权机制,它的最终目标是为第三方利用颁发一个有时效性的令牌 token,使得第三方利用可能通过该令牌获取相干的资源。

OAuth 2.0 比拟罕用的场景就是第三方登录,当你的网站接入了第三方登录的时候个别就是应用的 OAuth 2.0 协定。

另外,当初 OAuth 2.0 也常见于领取场景(微信领取、支付宝领取)和开发平台(微信开放平台、阿里开放平台等等)。

微信领取账户相干参数:

举荐浏览:

  • OAuth 2.0 的一个简略解释
  • 10 分钟了解什么是 OAuth 2.0 协定
  • OAuth 2.0 的四种形式
  • GitHub OAuth 第三方登录示例教程

8 什么是 SSO?

SSO(Single Sign On)即单点登录说的是用户登陆多个子系统的其中一个就有权拜访与其相干的其余零碎。举个例子咱们在登陆了京东金融之后,咱们同时也胜利登陆京东的京东超市、京东家电等子系统。

9.SSO 与 OAuth2.0 的区别

OAuth 是一个行业的规范受权协定,次要用来受权第三方利用获取无限的权限。SSO 解决的是一个公司的多个相干的自零碎的之间的登陆问题比方京东旗下相干子系统京东金融、京东超市、京东家电等等。

参考

  • https://medium.com/@sherryhsu/session-vs-token-based-authentication-11a6c5ac45e4
  • https://www.varonis.com/blog/what-is-oauth/
  • https://tools.ietf.org/html/rfc6749
正文完
 0