一文弄懂单点登录的几种技术选型
最近在搞一个单点登录的项目,顺便把单点登录的几种方案研究了一下,在这里汇总分析一下,让大家有一个整体的认识。
什么是单点登录
在介绍单点登录的方案前,先说明一下什么是单点登录?
单点登录(Single Sign On,简称 SSO),是指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权,无需再次登录。
它核心解决了一个问题:用户只需要登录一次,就可以访问所有相互信任的应用系统。
即,在单点登录体系(SSO)中,必然会涉及到下面几种角色:
- 多套系统应用:如果是单套的话,没必要SSO
- 登录用户:一套全局通行的用户中心
- SSO认证中心:用来实现登录认证的地址,只有这里说用户是可信的,这个用户才是可信的。
而且进一步划分,单点登录还可以细化分为两个部分:认证和授权。
认证:也可以称为鉴权,就是鉴定账号是否是可信的,是否系统约定的合法账号。
授权:就是给合法的账号授予一定的权限,比如只读权限,比如读写权限等。
在这个基础上, 单点登录的类型又可以分为细分为两种: 仅支持认证,和认证授权都支持。
常见的单点登录方案
简单介绍一下当前主流的单点登录方案,以及适用场景。
CAS
CAS(Central Authentication Service): 中心授权服务。顾名思义就是先有一个中心授权服务器,
其他的所有的业务服务器在需要身份认证的时候,都会向 中心授权服务 确认身份,鉴定是否合法。
这个过程中一般不涉及权限的管理,或者说权限的管理在各个子系统实现。
所以,CAS是一种仅支持认证的认证方案!但相对其他认证授权方案来说,CAS也足够简单。
对于大部分的应用场景来说,这就够了。因为CAS足够简单,很多场景也不需要权限管理,只需要鉴定访问是否合法就行了。
以下是cas协议架构:
cas请求认证的时序图:
应用场景:所有不需要权限管理的应用集群
- 后台服务器间的跨服务访问
- 普通的一处登录,处处访问
- 内部服务内部集群,因为内网的保护,彼此间天然就是可信的
OAuth2
OAuth2(Open Authorization): 开发授权协议。他的定位最开始是用于第三方免密登录和资源授权,比如使用微信免密登录微博。
因为这个特性,其天然的算是一种单点登录方案。
OAuth2支持认证和授权。与cas大多实在一个可信的内网环境不同,
OAuth2的核心目的是为了解决在完全不可信的网络环境下解决登录方与应用方的信任问题,并在此基础上提供了一套授权功能。
所以,OAuth2的定位和CAS还是不同的,那么相应的应用场景也就有了区别:
OAuth2的应用场景:
- 第三方免费登录某个应用系统
- 对于不同来源的用户设置不同的访问级别
- 企业内部的单点登录
OAuth2体系的角色划分:
- 资源拥有者(resource owner):比如登录用户
- 资源服务(resource server):用户的资源所存储的服务
- 客户端(client):用户现在需要登录的应用
- 授权服务(authorization server):授权认证的服务
还是以上面微信免密登录微博为例,一般在登录过程中,会提示我们授权微博使用微信的头像等信息,登录成功后,微博的头像就是微信的头像了:
- 资源拥有者:微信用户
- 资源服务:微信用户的一些信息提供方的服务,比如微信的头像、昵称等信息服务。简单来说就是微信服务器。
- 客户端:微信用户现在要登录的微博应用。
- 授权服务:微信的OAuth2授权服务。
OAuth2协议的架构图:
OAuth2选型流程图:
JWT
JWT(JSON Web Token),是一种用于在应用程序之间使用json的方式传递数据的安全令牌。严格来说,JWT不是一种sso协议,而是一种数据格式。
但是在sso协议过程中,生成的可信凭证,如果想在互联网这个不可信的环境下传输,JWT也就派上了用场。
结构
JWT由三部分组成:
- 头部(Header):包含签名算法、加密算法等信息。
- typ:令牌的类型,通常是JWT
- alg:签名算法,如HS256、RS256等。
- 负载(Payload):包含用户信息、权限信息等,可以包含以下字段以及任意自定义的字段。
- iss: Issuer。JWT的签发人,非必填
- sub: Subject。主题,JWT所面向的用户或实体的唯一标识符,非必填
- aud: Audience。受众,JWT的预期接收者,非必填
- exp: Expiration Time。过期时间,非必填
- nbf: Not Before。生效时间,JWT在此时间之前不可用,非必填
- iat: Issued At。签发时间,非必填
- jti: JWT ID。JWT的唯一标识,非必填
- 签名(Signature):将头部、负载和密钥进行签名。
- 前面算法:signature = HS256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)
最后形成一个Token字符串:xxx.yyy.zzz
, 即:
base64UrlEncode(header).base64UrlEncode(payload).signature
由此可见,JWT里的数据虽然经过base64编码,但是未加密,所以一般仅放一些公共信息。
不过因为其中也有通过密钥进行签名的环节,如果再配上加密算法对一些信息的加密,也可以当做一个无服务器化的极简版sso凭证:即能够正确解密识别JWT的凭证都是可信凭证。
但这仅是特殊场景的使用,一般情况还是将JWT当做CAS 或 OAuth2 的凭证在互联网中传输的载体。
OIDC
OIDC(OpenID Connect)协议,是在OAuth2 的基础上发展出来的一个协议,主要应用与身份的认证。
与OAuth2相比,OIDC衍生出了一个ID Token
的概念,用来标识登录用户的身份验证。
OIDC的角色划分:
- End User(EU):资源所有者,即用户,对应OAuth2中的资源拥有者;
- Relying Party(RP):指代在 OAuth 2.0 中,受信任的客户端,身份认证和授权信息的消费方;
- ID Token:OIDC新增,包含 EU 身份认证信息的 JWT 格式数据,是用户的身份凭证;
- OpenID Provider(OP):有能力提供身份认证的服务方, 对应OAuth2中的授权服务;
- UserInfo Endpoint:受 OAuth 2.0 保护的用户信息接口,此接口必须使用 HTTPS,能够当 RP 使用 ID Token 访问时返回用户的信息。
所以,相对于OAuth2,OIDC其设计更加精简,也更适用于sso的场景。 一般情况下,如果决定选型OAuth2,那么OIDC可能更好一点。
OIDC的架构图:
SAML
SAML(Security Assertion Markup Language)是一种基于XML的标准,用于在不同的安全域之间传递身份验证和授权数据,侧重于不同企业间身份认证。
涉及的角色:
- Service Provider(SP):服务提供方,
- Identity Provider(IdP):身份提供方,
SAML2的架构图:
由图中可以看出,SP和IdP之间的通信必须是通过浏览器来实现的。
SAML2的应用场景:
- 不同企业间的单点登录场景
- 因为使用了浏览器的重定向技术,适用于web场景,移动端的sso不要考虑
- 企业内部的不同Saas集成,比如一个账号登录不同的Saas应用
- SAML 2.0 支持数字签名、加密断言等功能,适用于对安全性要求较高的系统
总结
以上三种协议都支持单点登录功能。
从应用定位角度还是有些差异的:
- cas更适用于公司内部搭建轻量授权服务。
- OAuth/OIDC,是面向于在非信认条件下的信任授权问题,既支持认证,又支持授权。
- SAML,三者里面的老大哥,功能上与OAuth有点重叠。更重,但也更安全,适用于跨企业端通信。