本文首发于个人博客 https://teobler.com 转载请注明出处
在了解SSO是什么以前,咱们须要搞清楚两个概念: Authentication & Authorization
。html
Authentication(又被称为AuthN,身份验证),它指的是 the process of verifying that "you are who you say you are"
,也就是说这个过程是为了证实你是你。一般来讲有这么几个方式:浏览器
Single-factor
没有办法保证”你是你“,就会须要一些多重验证的手段,好比动态口令、生物识别等Authorization(又被称为AuthZ,权限验证),他指的是 the process of verifying that "you are permitted to do what you are trying to do"
,也就是说这个过程是为了证实你是否拥有作这件事的权限,好比修改某个表格等等,若是没有权限的话一般会返回 403
错误码。安全
在 SSO
出现以前,用户在不一样的系统登陆就须要在不一样的系统注册多个帐号,而后须要本身记住多个用户名和密码,而若是这些系统是同一个平台的话,其实该平台还须要维护多套几乎如出一辙的登陆系统,给用户和平台都带来了负担。服务器
而 SSO
就是一种authentication scheme(身份验证方案),SSO
容许用户使用同一个帐户登陆不一样的系统,很好地解决了上述的问题。它不但能够实现单一平台的登陆,假如某个平台以外的系统是信任该平台的,那么外部系统也能够集成这个平台的 SSO
, 好比如今的大多数网站都提供了 Google
帐号登陆的功能。微信
要实现 SSO
,首先须要你正在开发的系统信任这个第三方登陆系统所提供的用户信息,而后你须要按照必定的标准和协议去与其对接,接下来咱们会介绍两个比较经常使用的 SSO
协议 -- SAML 2.0 和 OIDC。session
SAML
是 Security Assertion Markup Language
的简称,是一种基于XML的开放标准协议,用于在身份提供者(Identity Provider简称IDP)和服务提供商(Service Provider简称SP)之间交换认证和受权数据。ide
SAML 2.0是该协议的最新版本,于2005年被结构化信息标准组织(OASIS)批准实行。post
SAML Assertion
,经过用户端传递给SPSAML Assertion
,没有问题的话就会返回相应的资源SAML Assertion
传递给这个新的SP,即可以实现不登陆直接访问资源那么这个 SAML Assertion
又是个啥呢?网站
首先用户为何能够访问SP上的资源呢?确定是由于其实SP也有一份用户的资料,这个资料里面可能有用户的帐户信息,权限等等,可是如今用户的信息是由IDP提供的,因此如今须要作的就是讲两份用户信息映射起来,好让SP知道IDP提供的用户究竟是哪个。加密
而这个映射的约定,就是SP和IDP进行集成的时候的一个配置,这个配置叫作 metadata
。这个配置有两份,两边各一份,里面约定了应该怎么去映射用户信息,签名的证书等。IDP和SP会经过别的方式去交换这两份 metadata
。
因此其实 SAML Assertion
里面包含了用户的惟一标识,可以证实该用户是谁。在SP拿到这份信息后就会按照一些规则去验证里面的信息是不是合法的用户。
那么问题来了,若是中间人知道了咱们之间的规则随便塞了一份信息进来咋办?因此其实 SAML Assertion
里面除了用户信息其实还有IDP的签名,只有SP先解析了里面的签名确认无误以后才会信任这份信息。
知道了 SAML Assertion
是个啥之后,咱们还须要弄清楚它是怎么发送出去的。要弄清楚它们是怎么发送出去的咱们须要知道一个东西叫作 binding method
。
SAML 2.0 有许多不一样的 binding
,它们其实就是 SAML Assertion
的交互方式:
其中如今用的比较多的是前三种,它们都是基于HTTP协议来实现的。
SAML Assertion
上面提到过 metadata
是为了让IDP和SP明白彼此交流的信息,而且有一些安全考虑,里面主要的信息有:
其中有一个字段 md:KeyDescriptor
在SP中有一个 encryption
,在SP和IDP进行通讯创建信任的时候,IDP就会拿到SP加密的key,在用户登陆成功后,IDP就会用这个key加密 SAML Assertion
,SP拿到后经过本身的私钥进行解密。另外一个叫 signing
的字段会被用来解析对方的签名,用来辨别这个 Assertion 是否是我想要的人发过来的。
OpenID Connect(OIDC) 是创建在 OAuth 2.0 协议之上的一个简单的身份层,它容许计算客户端根据受权服务器执行的认证,以 JSON 做为数据格式,验证终端用户的身份。它是 OpenID 的第三代规范,前面分别有 OpenID 和 OpenID 2.0。它在OAuth 2.0 的基础上增长了 ID Token 来解决第三方客户端标识用户身份认证的问题。
它的结构如图所示:
从它的结构图中能够看出,除了核心实现外,OIDC 还提供了一系列可选的扩展功能。好比:
因为图片距今已经有些年限了,其实如今OIDC还提供了许多可选的扩展,具体可到官网查看。
因为 OIDC 是基于 OAuth 2.0 的,因此 OIDC 也拥有多种 flow。因为篇幅所限我这里会相对详细地解释 Authorization Code Flow,在开始前咱们须要弄清楚几个名称:
ID Token:JWT格式的数据,包含 EU 身份认证的信息。ID Token 由 JWS 进行签名和 JWE 加密,从而提供认证的完整性、不能否认性以及可选的保密性。里面可能会有不少字段,详细能够看这里,其中这几个字段是必定包含其中的
RP 将 EU redirect 到 OP 端,并带上一些参数,这里列举一些必选参数,还有许多可选参数能够看这里
code
,token
,id_token
,none
中的一个或几个,在当前 flow 值为 code
Implicit Flow 是在 OP redirect EU 到 RP 的时候会带上 ID Token 和 Access Token(若是必要) 而不是 Authorization Code,同时在发送请求的时候也会有一些不一样,须要带上一些别的参数,这里就不细讲了,总的流程是差很少的,详情能够查看这里
Hybrid Flow 能够理解为上面两个 flow 的结合,OP redirect EU 到 RP 的时候会带上 Authorization Code,同时根据发送请求时候 Response Type 参数的不一样还会带上一些别的参数,具体流程能够参考这里
很是感谢你能看到这里,若是你以为有帮助到你,能够关注个人微信公众号