鉴权认证的基本概念

最近项目中用到,学习了一下。记录下来后续有时间再继续研究。

单点登录

单点登录SSO(Single Sign On)简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。单点登录在复杂多子系统里使用的非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉。实现单点登录说到底就是要解决如何产生和存储那个信任,再就是其他系统如何验证这个信任的有效性,因此要点也就以下两个:存储信任和验证信任。

session-cookie认证

session会话,代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续。cookie中存放着一个sessionID,请求时会发送这个ID。使用session-cookie做登录认证时,登录时存储session,退出登录时删除session,而其他的需要登录后才能操作的接口需要提前验证是否存在session,存在才能跳转页面,不存在则回到登录页面。

  • 服务器在接受客户端首次访问时在服务器端创建session,然后保存ssesion(我们可以将seesion保存在 内存中,也可以保存在redis中,推荐使用后者),然后给这个session生成一个唯一的标识字符串,然后在 响应头中种下这个唯一标识字符串。

  • 签名。这一步通过秘钥对sid(session ID)进行签名处理,避免客户端修改sid。(非必需步骤)

  • 浏览器中收到请求响应的时候会解析响应头,然后将sid保存在本地cookie中,浏览器在下次http请求的 请求头中会带上该域名下的cookie信息。

  • 服务器在接受客户端请求时会去解析请求头cookie中的sid,然后根据这个sid去找服务器端保存的该客 户端的session,然后判断该请求是否合法。

token

token是一个令牌,浏览器第一次访问服务端时会签发一张令牌,之后浏览器每次携带这张令牌访问服务端就会认证该令牌是否有效,只要服务端可以解密该令牌,就说明请求是合法的,令牌中包含的用户信息还可以区分不同身份的用户。一般token由用户信息、时间戳和由hash算法加密的签名构成。基于 Token 的认证现在已经越来越普遍。Token 和 Session ID 不同,并非只是一个 key。Token 一般会包含用户的相关信息,通过验证 Token 就可以完成身份校验。Token认证流程

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token(request头部添加Authorization),如果验证成功,就向客户端返回请求的数据,如果不成功返回401错误码,鉴权失败。
JWT
  1. JWT 的原理是,服务器认证以后,生成一个 JSON 对象,这个JSON对象肯定不能裸传给用户,那谁都可以篡改这个对象发送请求。因此这个JSON对象会被服务器端签名加密后返回给用户,返回的内容就是一张令牌,以后用户每次访问服务器端就带着这张令牌。这个JSON对象可能包含的内容就是用户的信息,用户的身份以及令牌的过期时间。

  2. 一个JWT形如:

SSO

它由三部分组成:Header(头部)、Payload(负载)、Signature(签名)。

  • Header部分是一个JSON对象,描述JWT的元数据。一般描述信息为该Token的加密算法以及Token的类型。{"alg": "HS256","typ": "JWT"}的意思就是,该token使用HS256加密,token类型是JWT。这个部分基本相当于明文,它将这个JSON对象做了一个Base64转码,变成一个字符串。Base64编码解码是有算法的,解码过程是可逆的。头部信息默认携带着两个字段。

  • Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。有7个官方字段,还可以在这个部分定义私有字段。一般存放用户名、用户身份以及一些JWT的描述字段。它也只是做了一个Base64编码,因此肯定不能在其中存放秘密信息,比如说登录密码之类的。

  • Signature是对前面两个部分的签名,防止数据篡改,如果前面两段信息被人修改了发送给服务器端,此时服务器端是可利用签名来验证信息的正确性的。签名需要密钥,密钥是服务器端保存的,用户不知道。算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。

  1. 客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。

Authorization: Bearer <token>
​ 另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面

Token和session的区别
  1. session-cookie的缺点:(1)认证方式局限于在浏览器中使用,cookie是浏览器端的机制,如果在app端就无法使用cookie。(2)为了满足全局一致性,我们最好把session存储在redis中做持久化,而在分布式环境下,我们可能需要在每个服务器上都备份,占用了大量的存储空间。(3)在不是Https协议下使用cookie,容易受到CSRF跨站点请求伪造攻击。(4)作为身份认证,token安全行比session好;
    Session 认证只是简单的把User 信息存储到Session 里,因为SID 的不可预测性,暂且认为是安全的。这是一种认证手段。 而Token ,如果指的是OAuth Token 或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对App 。其目的是让 某App有权利访问 某用户 的信息。
  2. token的缺点:(1)加密解密消耗使得token认证比session-cookie更消耗性能。(2)token比sessionId大,更占带宽。
  3. 两者对比,它们的区别显而易见:(1)token认证不局限于cookie,这样就使得这种认证方式可以支持多种客户端,而不仅是浏览器。且不受同源策略的影响。(2)不使用cookie就可以规避CSRF攻击。(3)token不需要存储,token中已包含了用户信息,服务器端变成无状态,服务器端只需要根据定义的规则校验这个token是否合法就行。这也使得token 的可扩展性更强。
OAUTH2.0

OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。OAuth 2.0 规范定义了一个授权(delegation)协议,对于使用Web的应用程序和API在网络上传递授权决策非常有用。OAuth被用在各钟各样的应用程序中,包括提供用户认证的机制。这导致许多的开发者和API提供者得出一个OAuth本身是一个认证协议的错误结论,并将其错误的使用于此。让我们再次明确的指出:

OAuth2.0 不是认证协议。

授权流程:主要是获取一段时间内有效的授权接入token ;access token

(1) Third-party application:第三方应用程序,本文中又称"客户端"(client)

(2)HTTP service:HTTP服务提供商,本文中简称"服务提供商",

(3)Resource Owner:资源所有者,本文中又称"用户"(user)。

(4)User Agent:用户代理,本文中就是指浏览器。

(5)Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。

(6)Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

处。

sso

(A)用户打开客户端以后,客户端要求用户给予授权。

(B)用户同意给予客户端授权。

(C)客户端使用上一步获得的授权,向认证服务器申请令牌。

(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。

(E)客户端使用令牌,向资源服务器申请获取资源。

(F)资源服务器确认令牌无误,同意向客户端开放资源。

access token:

其中access token访问令牌背后抽象的信息有哪些呢?如下3类信息。

  1. 客户端标识(比如第三方应用);
  2. 用户标识(比如user);
  3. 客户端能访问资源所有者的哪些资源以及其相应的权限。

有了这三类信息,那么资源服务器(Resouce Server)就可以区分出来是哪个第三方应用(Client)要访问哪个用户(Resource Owner)的哪些资源(以及有没有权限)。

Resource server:

在一般情况下,Resource server提供Authorization server服务,主要提供两类接口:

  1. 授权接口:接受Client的授权请求,引导用户到Resource server完成登陆授权的过程。
  2. 获取访问令牌接口:使用授权接口提供的许可凭据来颁发Resource owner的访问令牌给Client,或者由Client更新过期的访问令牌。

除此之外,还需要提供一个第三方应用程序注册管理的服务。通常情况下会为注册完成的第三方应用程序分配两个成对出现的重要参数:

  1. client_id:第三方应用程序的一个标识id,这个信息通常是公开的信息,用来区分哪一个第三方应用程序。
  2. client_secret:第三方应用程序的私钥信息,这个信息是私密的信息,不允许在OAuth2流程中传递的,用于安全方面的检测和加密
OIDC

OIDC是OpenID Connect的简称,OIDC=(Identity, Authentication) + OAuth 2.0。它在OAuth2上构建了一个身份层,是一个基于OAuth2协议的身份认证标准协议。我们都知道OAuth2是一个授权协议,它无法提供完善的身份认证功能(关于这一点请参考[认证授权] 3.基于OAuth2的认证(译)),OIDC使用OAuth2的授权服务器来为第三方客户端提供用户的身份认证,并把对应的身份认证信息传递给客户端,且可以适用于各种类型的客户端(比如服务端应用,移动APP,JS应用),且完全兼容OAuth2,也就是说你搭建了一个OIDC的服务后,也可以当作一个OAuth2的服务来用。

在OAuth2中,token被设计成是对客户端不透明的,但在用户身份认证的上下文环境中, 客户端往往需要能够从token中派生一些信息。这可以通过定义一个双重目的(dual-purposing)的客户端以解析和理解的token来完成。但是OAuth2协议并没有为access token本身定义特定的格式货结构,因此需要在OAuth2协议的基础上,利用诸如OpenId Connect的ID Token在响应中提供一个次要的标记,它将和access token一起发送给客户端中。一方面,保持了token是对客户端的不透明,另一方面,为客户端提供了其所需的认证信息。

OAuth2提供了Access Token来解决授权第三方客户端访问受保护资源的问题;OIDC在这个基础上提供了ID Token来解决第三方客户端标识用户身份认证的问题。OIDC的核心在于在OAuth2的授权流程中,一并提供用户的身份认证信息(ID Token)给到第三方客户端,ID Token使用JWT格式来包装,得益于JWT(JSON Web Token)的自包含性,紧凑性以及防篡改机制,使得ID Token可以安全的传递给第三方客户端程序并且容易被验证。此外还提供了UserInfo的接口,用户获取用户的更完整的信息。

OIDC流程:

从抽象的角度来看,OIDC的流程由以下5个步骤构成:

  1. RP发送一个认证请求给OP;
  2. OP对EU进行身份认证,然后提供授权;
  3. OP把ID Token和Access Token(需要的话)返回给RP;
  4. RP使用Access Token发送一个请求UserInfo EndPoint;
  5. UserInfo EndPoint返回EU的Claims。

ID Tokens介绍:

OpenID Connect是2014年初发布的开放标准,定义了一种基于OAuth2的可互操作的方式来来提供用户身份认证。实际上,它是众所周知的巧克力软糖的配方,已经被多数的专家们尝试和测试了。应用程序不必为每个潜在的身份提供程序构建不同的协议,而是可以将一个协议提供给多个提供程序。由于OpenId Connect是一个开放标准,所以可以自由的没有任何限制的和知识产权问题的来实现。OpenId Connect是直接建立在OAuth2之上的,在大多数情况下,部署在一个基于OAuth的基础设施之上。它还使用JOSN签名和加密规范,用来在传递携带签名和加密的信息。OpenId Connect避免了上面讨论的很多误区。

OIDC对OAuth2最主要的扩展就是提供了ID Token。ID Token是一个安全令牌,是一个授权服务器提供的包含**用户信息(由一组Cliams构成以及其他辅助的Claims)**的JWT格式的数据结构。OpenID Connect Id Token是一个签名的JSON Web Token(JWT:RFC7519),它和OAuth access token一起提供给Client应用程序。Id Token包含一组关于身份认证会话的声明(claim),包括用户的标识(sub)、颁发令牌的提供程序的标识符(iss)、以及创建此标识的Client的标识符(aud)。此外,Id Token还包含token的有效生存期(通常非常短)以及其他相关的上下文信息。由于Client知道Id Token的格式,因此它能直接分析出token的内容而无需依赖外部服务。此外,OpenId Connect还颁发access token给Client,允许Client保持对token的不透明,因为这是属于OAuth规范的一部分。最后,token本身是由提供程序的私钥进行签名的,除了在获取token中受TLS的保护之外,还添加了一个额外的保护层,以防止类似的模拟攻击。通过对此token的一些校验检查,Client可以保护自己免受大量常见的攻击。

由于Id token是授权服务器签名的,它还提供了在authorization code(c_hash)和access token(at_hash)上添加分离签名的位置,这些hash可以由Client来验证,同时仍保留authorization code和access token对Client不透明的语义,从而防止这一类的注入攻击。应该指出的是,Client不再需要使用access token,因为Id token已经包含了处理身份认证所需的所有信息。然而,为了保持和OAuth的兼容性,OpenId Connect会同时提供Id token和acces token。

UserInfo Endpoint除了Id token包含的信息之外,还定义了一个包含当前用户信息的标准的受保护的资源。如上所述,这些信息不是身份认证的一部分,而是提供附加的标识信息。比如说应用程序提示说“早上好:Jane Doe”,总比说“早上好:9XE3-JI34-00132A”要友好的多。它提供了一组标准化的属性:比如profile、email、phone和address。OpenId Connect定义了一个特殊的openid scope,可以通过access token来开启Id token的颁发以及对UserInfo Endpoint的访问。它可以和其他scope一起使用而不发生冲突。这允许OpenId Connect和OAuth平滑的共存。

openID Connect主要是对OAuth 2.0 能够使得终端用户通过ID Token的数据结构进行验证。当客户端和潜在的其他请求声明,ID Token包含声明的安全令牌并能在授权服务器中验证一个终端用户。ID Token表现为一个JSON Web Token(JWT)令牌。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值