学成总结(认证和授权)

本项目使用spring scurity + oauth2 + jwt 实现了认证授权完成了单点登录


Oauth2是一个标准的开放的授权协议,Spring security 是一个强大的和高度可定制的身 份验证和访问控制框架,Spring security 框架集成了Oauth2协议

Oauth2协议包含以下几种角色

1、客户端 本身不存储资源,需要经过认证才能访问资源,比如:学成在线Android客户端、学成在 线Web客户端(浏览器端)、微信客户端等。
2、资源拥有者
通常为用户,也可以是应用程序,即该资源的拥有者。
3、授权服务器(也称认证服务器)
单独的认证系统,想要访问资源必须得到授权服务器的认证
4、资源服务器
存储资源的服务器,其实就是我们平时开发的微服务,比如课程微服务、cms微服务

Oauth2协议有以下授权模式:
授权码模式(Authorization Code) 隐式授权模式(Implicit) 密码模式(Resource Owner Password Credentials) 客户端模式(Client Credentials)

本系统使用的是密码模式 这里说下流程

  1. 用户(客户端)访问资源时需要先登录(请求认证服务器进行认证)
  2. 认证服务器调用用户中心微服务得到用户信息进行认证,认证成功会根据用户的一些信息(包含权限信息)生成一个jwt令牌,(JWT令牌生成采用非对称加密算法,利用私钥生成令牌,利用公钥解析令牌)
    这个令牌包含着一个短的身份令牌,一个长的jwt授权令牌,认证服务器会把这个短的身份令牌设置进cookie返回给客户端,然后会以这个短的身份令牌为key,以长的授权jwt令牌为value放入redis中
  3. 这个时候客户端的cookie中有了短的身份令牌,需要带着这个cookie再次请求认证服务得到那个长的jwt(认证服务器从redis中取)解析他之后得到用户信息,客户端就可以展示已经完成认证的用户信息(登录完成)解析完之后 把这个长的jwt令牌放入sessionstroge中
  4. 这个时候完成认证(登录成功)的用户如果点击退出,那么客户端会请求认证服务器的退出接口,这个接口会把cookie中短的身份令牌和redis中长的授权令牌全部删掉。
  5. 这个时候完成认证(登录成功)的用户如果访问资源服务器的资源必须在Authorization头信息中带着长的授权令牌,然后会被后台的zuul网关拦截,这个网关配的拦截器会判断该请求的cookie中是否带着短的身份令牌、头信息的Authorization中是否带着长的授权令牌、根据这2个令牌能在redis中找到对应的信息。只要这3个条件有一个不满足就会返回错误。
  6. 如果3个条件都满足,那么成功访问到资源服务器,但不意味着资源服务器中所有的资源都可以访问,资源服务器会解析这个jwt令牌中的权限信息,如果权限不满足对应资源所需要的权限那么会返回权限不足。(资源所对应方法上配了security的权限注解)
  7. 学成总结(认证和授权)_第1张图片

注意:
cookie中短的身份令牌并不包含具体的用户信息,只是用于一个标识让客户端再次访问认证服务器拿到那个包含用户信息的长的授权令牌,拿到解析之后得到用户信息。
为什么不直接设置长的授权令牌进cookie?
因为太长了 cookie放不下

为什么要用jwt?

传统授权方法的问题是用户每次请求资源服务,资源服务都需要携带令牌访问认证服务去校验令牌的合法性,并根 据令牌获取用户的相关信息,性能低下。

解决:
使用JWT的思路是,用户认证通过会得到一个JWT令牌,JWT令牌中已经包括了用户相关的信息,客户端只需要携带 JWT访问资源服务,资源服务根据事先约定的算法自行完成令牌校验,无需每次都请求认证服务完成授权。

总结下优点:

  • 基于json 解析十分方便
  • 通过非对称加密算法及数字签名技术加密,安全性很高
  • 资源服务器不需要通过认证服务器可以自行根据算法解析令牌进行授权

缺点:JWT令牌较长,占存储空间比较大。

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

学成总结(认证和授权)_第2张图片
学成总结(认证和授权)_第3张图片
第二部分是负载,内容也是一个json对象,它是存放有效信息的地方,它可以存放jwt提供的现成字段,比 如:iss(签发者),exp(过期时间戳), sub(面向的用户)等,也可自定义字段。
学成总结(认证和授权)_第4张图片
学成总结(认证和授权)_第5张图片
第三部分将base64加密后的header和base64加密后的payload用.连接起来组成字符 串,然后通过header中声明的算法和secret(密钥)组合加密,然后就构成了jwt的第 三部分。

生成jwt的时候只要根据需要加自定义的内容并且指定算法和密钥就OK。

本项目生成jwt采用的是RSA非对称加密算法,生成jwt和解析jwt的密钥是不一样的,包含一个公钥和一个私钥,
认证服务器生成jwt采用的是密钥,资源服务器解析jwt采用的是私钥。

我们利用了keytool工具 生成了一个证书,这个证书中包含了公钥和私钥,在生成和解析jwt的时候指定就可以了。
认证服务器保存了一个密钥
资源服务器保存了一个公钥

具体步骤还是看讲义把。。

你可能感兴趣的:(学成总结)