SSO单点登录的流程

Aug 30, 2016


前言

我在公司这两年接触最多的产品应该就是sso了吧,其实现在很多公司都有sso产品,他们的规范也不尽相同,其实现在是有一个sso的标准协议的,叫做openId,现在非常多的互联网厂商都基于这个协议做了开放单点登录,比如腾讯,新浪,百度等,所以我们经常可以在第三方网站上使用这些厂商的账号安全的登录。

实际上,单纯的sso单点登录往往是满足不了需求的,因为登录之后第三方应用必须自己保存用户信息,而此时的用户信息又很少,所以多数情况下需要向登录验证服务获取更多用户信息,这个过程要获得用户授权以保证用户信息安全,于是就有了用来获取用户资源的协议OAUTH,最初的OAUTH已经因为安全漏洞被抛弃了,现在大部分使用的是OAUTH2协议。

openId和oauth2是两个不相关的协议,当时多数情况下,这两个协议需要共同配合来满足需求,在这个基础下,出现了一个整合这两者的协议,OpenId Connect协议,这个协议基于OAuth2,包含了openId2.0登录的协议。

本文主要讨论的是基于openId协议的单点登录过程和实现原理。

单点登录中的角色

openId中一共有三个角色

  • 最终用户(End User)
  • 外部应用(Relying Party)
  • 认证服务器(OpenID Provider)

这里最终用户一般是通过浏览器作为用户代理上网的,外部站点指的是最终用户想要登录的站点,认证服务器指的是单点登录服务器。

单点登录流程

openId单点登录的流程一般有两类:

  • 直接登录
  • 间接登录

直接登录指的是用户将账号的密码交给外部应用,外部应用直接使用用户的账号密码登录获得用户信息,这种情况外部应用可以得到用户的账号和密码,因此必须是受用户信任的应用。 间接登录指的是需要先跳转到认证服务器,然后用户在认证服务器登录之后再返回外部应用。

直接登录的流程相对比较简单,只要用户将用户名密码输入第三方应用,第三方通过http请求直接取得用户信息即可,这里我们主要分析间接登录的流程。

间接登录流程如下:

enter description here

从流程中可以看出,最终用户访问外部站点时:

  • 外部站点首先返回一个重定向响应,要求最终用户到认证服务器登录;
  • 最终用户自动跳转到认证服务器的登录页面。此时认证服务器要求用户输入用户名和密码进行登录;
  • 用户输入用户名密码之后,提交到认证服务器,认证服务器校验用户名密码通过之后,就返回一个带着认证信息的重定向响应,告诉最终用户认证成功了,可以回到外部应用了;
  • 最终用户带着认证信息回到外部应用,外部应用获取到认证信息之后,带着认证信息先访问了认证服务器确认认证信息;
  • 外部应用的认证信息得到认证服务器的确认之后,确认用户可以登录,于是就在本地给用户登录并返回用户想要访问的页面。

我们可以看到,在这个过程中,外部应用并没有得到用户的用户名和密码,只得到认证服务器的认证信息,因此这个过程中用户的用户名密码是安全的,不会泄露给外部 应用。

需要解决的问题

在上面我们已经知道openId的登录流程了,但是这里有两个关键的问题需要解决:

  • 多个应用如何实现一次登录?
  • 验证信息如何传递?

对于多应用实现一次登录的问题,一般是通过cookie实现的,用户在认证服务器登录完成之后,认证服务器在本域名下写一个cookie记录认证信息,当用户在第二个外部应用跳转过来时,先检查cookie,发现验证信息之后,直接校验验证信息,如果校验通过,则直接带着验证信息返回外部应用即可,如果验证不通过,则要求用户重新登录。

对于第二个问题,验证信息的传递一般通过url带着授权信息交给外部应用。在openId connect协议中,这个授权信息称为授权码。关于openId connect协议,包含了oauth2协议,不在本文的讨论范围中,下次再讨论吧。