登录与授权之我见

文章介绍了统一身份认证(UIM)和单点登录(SSO)的概念及其在企业中的应用。统一认证解决了用户在多系统中重复登录和权限管理的问题,通过身份提供方(IdP)统一管理用户身份和权限。单点登录则允许用户一次登录后访问多个系统,但不涉及权限管理。文章还探讨了SSO和UIM的运行流程,以及它们与微服务场景中登录态传递的相似性。

文章目录

引子

到了新学校之后,我发现校内大多数网站应用在登录时都会跳转到一个统一认证站点,在你输入用户名密码点击登录后就能访问应用的内容,这套流程使得你只需要记住一份密码便可以访问校内许多不同的应用,诸如教务系统、学工系统等。当时觉得十分方便,但也没有仔细研究下去。

统一身份认证

而在我进入信息中心开始进行项目开发后,由于需要接入统一认证,才开始深入了解这方面内容。

概念&问题

认证(authentication)授权(authorization) ,是应用服务中重要的一环,认证是为了解决验证用户的身份,即回答“你是合法用户吗?”;而授权则是为了判断用户能否进行特定操作,即回答“你有权这么做吗?”。

传统的web单体应用,每个应用需要自己实现一套认证授权的逻辑,即从登录到鉴权。想象这么一个场景:

在一家公司内部有着若干业务系统:请假系统、人力资源管理、财务系统、进销存管理、设备管理、客户关系管理等等。。。这时管理员需要给新入职的工程师小z分配这些系统的账号,而小z需要记住并维护这些不同系统的账号密码,如果这些系统的密码强度要求不同,天哪!

若干年后,小z晋升为项目经理,于是管理员又需要为小z在不同系统中设置不同的权限,又是一件麻烦的事情。又是若干年后,小z从公司离职,管理员需要清理小z在公司内各个系统的账号,这时别说是管理员,怕是小z自己都记不太清到底在多少个系统中留有账号了。

解决方案

为了解决上述问题,人们引入了单点登录(Single Sign-On,简称SSO)统一认证(Unified Identity Management,简称UIM) 的概念,两者解决的问题类似,但应用范围有所不同。这里先引入几个概念,方便后面的介绍:

身份提供方(Identity Provider):简称IdP,负责用户身份认证和授权服务,提供用户登录到其他系统的统一入口。

资源服务(Resource Server):提供数据或业务功能的业务系统,在web应用中通常指提供API服务的后端。

客户端(Client):使用户能通过凭证(身份令牌)对资源服务进行操作的应用程序,即前端。

单点登录

根据我的理解,单点登录允许用户在一次登录后,可以访问多个不同的应用而无需为每个应用单独进行认证,常见的应用场景为各种第三方登录(比如使用QQ登录不同的游戏,使用Github登录各种开发工具如Jetbrains全家桶、VSCode等)。可以说,单点登录实现了一次登录,处处通行!

单点登录不要求IdP储存每个用户在对应资源服务下的权限信息,在SSO场景下,IdP只为资源服务提供用户的身份信息,让资源服务能够识别唯一的用户,对于资源服务来说,把用户的权限信息储存在第三方的IdP也并不安全。

在小z公司的例子中,管理员引入了单点登录,配备了统一用户中心,将所有业务系统的登录行为都重定向到统一用户中心的登录接口*(这里先不讨论如何实现)*。那么小z在入职时管理员只需要为其分配一个新的的账号,通过这个账号,小z就可以登录到公司内任何一个业务系统,小z离职时也只需禁用一个账号即可。但是问题并没有完全解决,由于IdP不储存用户在每个业务系统下的权限信息,所以管理员仍需要在每个系统中单独修改账号的权限。所以下面将要介绍更适合企业内部使用的统一认证方案。

统一认证

统一认证在单点登录的基础上还增加了权限管理和访问管理,更关注身份认证和授权管理,适合企业内部使用。比如小z的例子中,公司将统一用户中心升级为统一认证中心,现有业务系统配合改造登录授权模块。这下管理员可以通过统一认证中心管理所有账号的信息及在每个业务系统下的权限,而无论是请假系统、财务系统还是人力资源管理系统,只需要遵循标准获取用户的权限信息即可对用户进行鉴权。并且当公司添加了新的业务系统时,只需要在IdP添加新的系统信息及权限信息,就可以无缝接入。

这下无论是管理员还是员工,都享受到了统一认证带来的便利。

运行流程

老规矩,遇到复杂功能使用思维导图表达更清晰,下图将单点登录场景下用户访问资源服务的整个流程绘制了出来。其中,红旗图标为起点,深蓝色和深紫色的节点代表不同分支。

SSO

资源服务获取用户信息一般有两种方式:

  1. IdP将用户信息放在JWT令牌中传递出去。
  2. 资源服务通过IdP提供的API获取用户信息。

而统一认证的流程与单点登录基本一致,主要区别在于鉴权步骤。资源服务无需自己储存用户权限,而是通过令牌或通过IdP提供的API查询用户权限信息。

额外思考

到这里似乎就告一段落了,如今已经有不少成熟的SSO方案,比如OIDC协议,开源轮子并不缺少。但是从这个问题中我们可以发现与微服务场景中传递登录态相似的地方,SSO和UIM场景中需要在不同资源服务中传递用户认证信息,而微服务场景中也需要在各个微服务之间传递登录态,这两者采取的解决方案也是十分相似的:JWT令牌、API验证、会话共享等,只不过考虑到性能和数据安全而互有取舍。