• 常用认证机制


    一、HTTP Basic Auth

    介绍:
    HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RESTful API 使用的最简单的认证方式,只需提供用户名密码即可。
    弊端:
    由于有把用户名密码暴露给第三方客户端的风险,在生产环境下被使用的越来越少。因此,在开发对外开放的RESTful API时,尽量避免采用HTTP Basic Auth。

     

    二、Cookie-session Auth

    介绍:
    Cookie-session 认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie对象;通过客户端带上来Cookie对象来与服务器端的session对象匹配来实现状态管理的。默认的,当我们关闭浏览器的时候,cookie会被删除。但可以通过修改cookie 的expire time使cookie在一定时间内有效;但是这种基于cookie-session的认证使应用本身很难得到扩展,随着不同客户端用户的增加,独立的服务器已无法承载更多的用户,而这时候基于session认证应用的问题就会暴露出来。
    弊端:
    Session:每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。
    扩展性:用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

    三、Token Auth

    介绍:
    基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。
    弊端:
    这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端设置Access-Control-Allow-Origin就可以了。

    优势:
    支持跨域访问:Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输。
    无状态(服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息。
    更适用CDN:可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可。
    解耦:不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可。
    更适用于移动应用:当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
    CSRF(跨站请求伪造Cross-site request forgery):因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。

    Token-JWT

    介绍:
    Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。

    相对于Cookie-Session优势:
    简洁:JWT Token数据量小,传输速度也很快、因为JWT Token是以JSON加密形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持
    不需要在服务端保存会话信息,也就是说不依赖于cookie和session,所以没有了传统session认证的弊端,特别适用于分布式微服务。
    单点登录友好:使用Session进行身份认证的话,由于cookie无法跨域,难以实现单点登录。但是,使用token进行认证的话, token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie,不会存在这些问题。
    适合移动端应用:使用Session进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到Cookie(需要 Cookie 保存 SessionId),所以不适合移动端。

          Token-JWT 构成

    JWT的构成
    第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).
    JWTString=Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

    Header
    JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存。
    Payload
    有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。
    请注意,默认情况下JWT是未加密的,因为只是采用base64算法,拿到JWT字符串后可以转换回原本的JSON数据,任何人都可以解读其内容,因此不要构建隐私信息字段,比如用户的密码一定不能保存到JWT中,以防止信息泄露。JWT只是适合在网络中传输一些非敏感的信息。
    Signature
    签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。

    注意JWT每部分的作用,在服务端接收到客户端发送过来的JWT token之后:header和payload可以直接利用base64解码出原文,从header中获取哈希签名的算法,从payload中获取有效数据signature由于使用了不可逆的加密算法,无法解码出原文,它的作用是校验token有没有被篡改。服务端获取header中的加密算法之后,利用该算法加上secretKey对header、payload进行加密,比对加密后的数据和客户端发送过来的是否一致。注意secretKey只能保存在服务端,而且对于不同的加密算法其含义有所不同,一般对于MD5类型的摘要加密算法,secretKey实际上代表的是盐值。

    四、OAuth

    介绍:

    OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。oAuth是Open Authorization的简写。

    OAuth发展历史:

    2007年发布了OAuthCore 1.0:此版本的协议存在严重的安全漏洞。
    2009年6月发布了OAuthCore 1.0 Revision A:修复了前一版本的安全漏洞,并成为RFC5849。
    2010年4月发布了OAuth2.0,是OAuth协议的下一版本,但与OAuth 1.0版本互不兼容。

    颁发令牌(OAuth 的核心就是向第三方应用颁发令牌):

    授权码(authorization-code)
    隐藏式(implicit)
    密码式(password):
    客户端凭证(client credentials)

     Oauth-授权码模式

    授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。

     Oauth-隐藏式模式

    介绍:
    有些 Web 应用是纯前端应用,没有后端,必须将令牌储存在前端。
    第一步,A 网站提供一个链接,要求用户跳转到 B 网站,授权用户数据给 A 网站使用。
    https://b.com/oauth/authorize?  response_type=token&  client_id=CLIENT_ID&  redirect_uri=CALLBACK_URL&  scope=read
    上面 URL 中,response_type参数为token,表示要求直接返回令牌。
    第二步,用户跳转到 B 网站,登录后同意给予 A 网站授权。这时,B 网站就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。
    https://a.com/callback#token=ACCESS_TOKEN
    上面 URL 中,token参数就是令牌,A 网站因此直接在前端拿到令牌。
    注意,令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。
    这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。

     Oauth-密码式模式

    介绍:
    如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。
    第一步,A 网站要求用户提供 B 网站的用户名和密码。拿到以后,A 就直接向 B 请求令牌。
    https://oauth.b.com/token?  grant_type=password&  username=USERNAME&  password=PASSWORD&  client_id=CLIENT_ID
    上面 URL 中,grant_type参数是授权方式,这里的password表示"密码式",username和password是 B 的用户名和密码。
    第二步,B 网站验证身份通过后,直接给出令牌。注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,A 因此拿到令牌。
    这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。

    Oauth-凭证式模式

    介绍:
    适用于没有前端的命令行应用,即在命令行下请求令牌。
    第一步,A 应用在命令行向 B 发出请求。https://oauth.b.com/token?  grant_type=client_credentials&  client_id=CLIENT_ID&  client_secret=CLIENT_SECRET
    上面 URL 中,grant_type参数等于client_credentials表示采用凭证式,client_id和client_secret用来让 B 确认 A 的身份。
    第二步,B 网站验证通过以后,直接返回令牌。
    这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

  • 相关阅读:
    【JavaEE进阶序列 | 从小白到工程师】JavaEE中的Stream流的常用方法
    C#/.NET/.NET Core优秀项目和框架2024年1月简报
    Xcode报错“compact unwind compressed function offset doesn‘t fit in 24 bits
    C语言求数组最小值,并返回下标
    redis(其它操作、管道)、django中使用redis(通用方案、 第三方模块)、django缓存、celery介绍(celery的快速使用)
    kotlin 消除强制非空!!
    请教下Elasticsearch7.14向量检索
    飞书Webhook触发操作指南,实现事件驱动型工作流自动化
    安装xilinx烧写器驱动
    kaldi安装流程
  • 原文地址:https://blog.csdn.net/juanxiaseng0838/article/details/126268322