大家好,我是陈哈哈。单点登录SSO的出现是为了解决众多企业面临的痛点,场景即用户需要登录N个程序或系统,每个程序与系统都有不同的用户名和密码。在企业发展初期,可能仅仅有几个程序时,管理账户和密码不是一件难事。但是发展到有数十、百、千计的应用程序时,纵然是千手观音也是异常困难,毕竟脑子不是多线程。
本文将从统一认证中的
认证与授权
、SSO单点登录
、四种安全认证协议
、四种认证协议比较
几个方面展开聊聊,希望对你有所收货。
投稿素材:富贵人家的猫
作者:二凝
目录
- 一、认证与授权
- 🍓Authentication 认证(who am I ?)
- 🍓Authorization 授权(what can i do ?)
- 二、统一认证 - SSO单点登录
- 🍓JWT协议
- 🍋JWT优势
- 🍋JWT协议 - Token组成
- 🍋JWT协议 - Header
- 🍋JWT协议 - Payload
- 🍋JWT协议 - Signature
- 🍓OAuth2协议
- 🍋OAuth2协议 - 应用场景
- 🍋OAuth2协议 - 协议特点
- 🍋OAuth2协议 - 授权模式
- 🍓OpenID Connect协议
- 🍋OpenID Connect协议 - IDToken的意义
- 🍓SAML协议
- 🍋SAML协议 - 参数
- 🍋SAML协议 - SAML的缺点
- 🍓CAS协议
- 🍋CAS协议 - 认证过程:
- 🍋CAS协议 - 授权过程:
- 三、四种认证协议比较
一、认证与授权
在开发的过程中,常常听说认证(Authentication)和授权(Authorization),它们的缩写都为auth,所以非常容易混淆。
🍓Authentication 认证(who am I ?)
例:给快递小哥出示身份证证明你是你,小哥把快递给你。
认证(Authentication)是验证用户提供的或者存储在系统的证书,证明用户就是他们所说的人的过程。如果证书相符,就授予访问权,如果不符,就拒绝访问。
🍓Authorization 授权(what can i do ?)
例:你向快递员出示了身份证,然后你又把你房门的密码给了他,并告诉他说,我把房门密码给你,你帮我放到我客厅里吧。
授权指的是你被允许访问应用的某个区域或者运行特定的行为,允许是建立在应用的特定标准和条件下的。它也被称为访问控制或者权限控制。
授权可以授予或者拒绝执行任务、访问应用某些区域的权利。
二、统一认证 - SSO单点登录
单点登录英文全称 Single Sign On,简称 SSO。它的定义是:在多个应用系统中,用户只需要登录一次,即可访问所有相互信任的应用系统。SSO 服务用于解决同一公司不同业务应用之间的身份认证问题,只需要登录一次,即可访问所有添加的应用。
主流单点登录SSO技术方案(安全认证协议)包括下午五种:
- JWT单点登录协议
- OpenID Connect (OIDC) 单点登录协议
- OAuth 2.0单点登录协议
- SAML 单点登录协议
- CAS 单点登录协议
🍓JWT协议
Json web token ( JWT ), 是一种用于双方之间传递安全信息的简洁的表述性声明规范。JWT作为一个开放的标准(RFC 7519),定义了一种简洁的方法用于通信双方之间以 Json 对象的形式安全地传递信息,该 token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。
🍋JWT优势
- 体积小(一串字符串)。因而传输速度快;
- 传输方式多样。可以通过 HTTP 头部(推荐)/URL/POST 参数等方式传输;
- 严谨的结构化。它自身(在 payload 中)就包含了所有与用户相关的验证消息,如用户可访问路由、访问有效期等信息,服务器无需再去连接数据库验证信息的有效性,并且 payload 支持应用定制;
- 支持跨域验证。多应用于单点登录;
🍋JWT协议 - Token组成
token组成(xxxx.yyyy.zzzz):
- Header
- Payload
- Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VybmFtZSI6InRlc3QiLCJpYXQiOjE1OTM5NTU5NDMsInVpZCI6MTAsImV4cCI6MTU5Mzk1NTk3Mywic2NvcGVzIjpbImFkbWluIiwidXNlciJdfQ.
VHpxmxKVKpsn2Iytqc_6Z1U1NtiX3EgVki4PmA-J3Pg
🍋JWT协议 - Header
Header通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法(例如HMAC SHA256或RSA)。 例如:
{"alg": "SHA256","typ": "JWT"
}
Header会被Base64Url编码为JWT的第一部分。即为:
$ echo -n '{"alg":"HS256","typ":"JWT"}'|base64↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
🍋JWT协议 - Payload
这些是一组预定义的权利要求,不是强制性的,而是建议使用的,以提供一组有用的可互操作的权利要求。其中一些是: iss(JWT的签发者), exp(expires,到期时间), sub(主题), aud(JWT接收者),iat(issued at,签发时间),nbf(在此之前不可用),jti(JWT ID用于标识该JWT)等。
{ "iat": 1593955943, "exp": 1593955973, "uid": 10, "username": "test", "scopes": [ "admin", "user" ]
}
Payload会被Base64Url编码为JWT的第二部分。即为:
$ echo -n '{"iat":1593955943,"exp":1593955973,"uid":10,"username":"test","scopes":["admin","user"]}'|base64↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓eyJ1c2VybmFtZSI6InRlc3QiLCJpYXQiOjE1OTM5NTU5NDMsInVpZCI6MTAsImV4cCI6MTU5Mzk1NTk3Mywic2NvcGVzIjpbImFkbWluIiwidXNlciJdfQ
🍋JWT协议 - Signature
Signature部分的生成需要base64编码之后的Header,base64编码之后的Payload,密钥(secret),Header需要指定签字的算法。
Signature:
HMACSHA256(
base64UrlEncode(header)
+ “.” +
base64UrlEncode(payload)
,
secret
)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VybmFtZSI6InRlc3QiLCJpYXQiOjE1OTM5NTU5NDMsInVpZCI6MTAsImV4cCI6MTU5Mzk1NTk3Mywic2NvcGVzIjpbImFkbWluIiwidXNlciJdfQ.
VHpxmxKVKpsn2Iytqc_6Z1U1NtiX3EgVki4PmA-J3Pg
🍓OAuth2协议
OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他 们数据的所有内容。OAuth在全世界得到广泛应用,目前的版本是2.0版。
🍋OAuth2协议 - 应用场景
- 原生app授权:app登录请求后台接口,为了安全认证,所有请求都带token信息,如果登录验证、 请求后台数据。
- 前后端分离单页面应用:前后端分离框架,前端请求后台数据,需要进行oauth2安全认证。
- 第三方应用授权登录,比如QQ,微博,微信的授权登录。
🍋OAuth2协议 - 协议特点
- 简单:不管是OAuth服务提供者还是应用开发者,都很易于理解与使用;
- 安全:没有涉及到用户密钥等信息,更安全更灵活;
- 开放:任何服务提供商都可以实现OAuth,任何软件开发商都可以使用OAuth;
🍋OAuth2协议 - 授权模式
客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0一共分成四种授权类型(authorization grant)
授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
授权码模式和密码模式比较常用。
第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。
🍓OpenID Connect协议
OpenID Connect简称为OIDC,是基于OAuth2.0扩展出来的一个协议。 它在OAuth2上构建了一个身份层用于认证,是一个基于OAuth2协议的身份认证标准协议。可以说OIDC协议是当今最流行的协议。
OAuth2实际上只做了授权,而OpenID Connect在授权的基础上又加上了认证。
OIDC的优点是:简单的基于JSON的身份令牌(JWT),并且完全兼容OAuth2协议。
OpenID(认证)+
OAuth 2.0(授权)
=OpenID Connect(认证+授权)
OIDC协议的登陆授权流程和OAuth2.0基本类似, 整个流程的参与者也类似,相比OAuth2,OIDC引入了id_token等和userinfo相关的概念:
- 整个OAuth2协议,只是定义了access_token/refresh_token,但是这俩token只是为了保护Resource Server的,并没有Resource Owner的身份信息;
- OIDC引入了id_token的概念,用这个特殊的token来表示这是Resource Owner的身份证;
- 标准化id_token的格式:即大家熟知的JWT;
- 标准化id_token的内容:Standard Claims
- OIDC引入了关于如何获取详细userinfo的Endpoint;
🍋OpenID Connect协议 - IDToken的意义
- 在access token添加用户身份信息,可能导致用户信息泄露;
因为每次接口请求都携带access token,其payload部分的用户信息是可解析的,相当于是明文的;
-
access token目的是用于接口访问的凭证,如果同时包含用户信息的话,功能就不分离了;
-
使用idToken替换userinfo endpoint获取用户信息,减少请求开销;
一般oauth2协议,都提供userinfo endpoint获取用户信息,例微软:https://graph.microsoft.com/oidc/userinfo,使用access token调用此接口获取得到用户信息;idToken可节省调用userinfo API接口的额外消耗;
- 某些场景,如只需要用户登录认证并获取用户信息,而不必调用Resource Server的其他API;那么这种场景只需要返回idToken,accessToken将不必返回;
从权限范围方面来看:OAuth2 > OpenID Connect
。
现在很多网站都提供了「使用微信快速认证」(也就是 OAuth2 )作为登录方式。但当你不确定这个网站是否可信时,这样做是危险的。因为 OAuth2授权登录后,就相当于把你微信的部分数据(比如名称、图像、手机号)和权利(比如发私信)交给了这个网站,至于网站要做什么你根本不知道。
而 OpenID Connect 只是告诉网站或别人,这个帐号是你而已,并不会也无法提供其它数据。
🍓SAML协议
SAML 是 Security Assertion Markup Language 的简称,是一种基于XML的开放标准协议,用于在身份提供者(Identity Provider简称IDP)和服务提供商(Service Provider简称SP)之间交换认证和授权数据。
- IDP:账号认证的服务方(统一认证)
- SP:向用户提供商业服务的软件(实体),比如全预约子系统
- User Agent:web浏览器
- 用户试图登录 SP 提供的应用。
- SP 生成 SAML Request,通过浏览器重定向,向 IdP 发送 SAML Request。
- IdP 解析 SAML Request 并将用户重定向到认证页面。
- 用户在认证页面完成登录。
- IdP 生成 SAML Response,通过对浏览器重定向,向 SP 的 ACS 地址返回 SAML Response,其中包含 SAML Assertion 用于确定用户身份。
- SP 对 SAML Response 的内容进行检验。
- 用户成功登录到 SP 提供的应用。
在第一步,SP将会对该资源进行相应的安全检查,如果发现浏览器中存在有效认证信息并验证通过,SP将会跳过2-6步,直接进入第7步。
如果在第一步的时候,SP并没有在浏览器中找到相应的有效认证信息的话,则会生成对应的SAMLRequest,并将User Agent重定向到IdP。
🍋SAML协议 - 参数
🍋SAML协议 - SAML的缺点
- 协议复杂:SAML协议的文档较大,用户可能需要更多的时间来理解协议,熟悉它的使用方法。
- 实施成本偏高:SAML需要积极支持Security Assertion Markup Language (SAML)的服务器软件,而这些服务器软件的安装和配置可能比较昂贵。
- 手机APP中兼容性较差:SAML需要通过HTTP Redect和HTTP POST协议来传递用户信息,并且通常是通过FORM表单的格式来进行数据的提交的。
🍓CAS协议
CAS全称为Central Authentication Service即中央认证服务,是一个企业多语言单点登录的解决方案,并努力去成为一个身份验证和授权需求的综合平台。
- CAS Server需要独立部署,主要负责对用户的认证工作;
- CAS Client负责处理对客户端受保护资源的访问请求,若需要登录,重定向到CAS Server。
🍋CAS协议 - 认证过程:
- 用户访问应用系统,应用系统需要用户认证,则重定向到CAS服务器;
- 用户在CAS服务器上输入用户名和密码,CAS服务器验证用户账号和密码;
- 验证成功后,CAS服务器生成一个Ticket,并重定向回应用系统;
- 应用系统拿着Ticket去CAS服务器上验证,验证成功后,CAS服务器返回一个有效的用户账号(可以是用户名、邮箱等);
- 应用系统使用返回的用户账号进行本地的用户认证,认证成功后,用户即可登录应用系统。
🍋CAS协议 - 授权过程:
- 用户登录应用系统后,需要访问某个资源;
- 应用系统将用户的访问请求发送到CAS服务器,并携带用户的身份信息;
- CAS服务器验证用户的身份信息,并根据用户的权限,判断用户是否有权访问该资源;
- CAS服务器返回授权结果给应用系统;
- 应用系统根据CAS服务器返回的授权结果,决定是否允许用户访问该资源。
用户访问不同语言、不同架构的服务,服务又通过CAS、SAML、Oauth等协议与认证服务器进行交互,基于spring mvc框架的认证服务器从LDAP、数据库、或AD获取数据对用户进行身份验证,然后向用户颁发凭据。
当前版本的CAS集成的身份验证机制有AD、Generic、LDAP、JDBC等等,由于发展的需要,现在的CAS已经支持其他的一些身份协议,例如OIDC、Oauth 2.0等等。
三、四种认证协议比较
将OIDC、OAuth 2.0、SAML2、CAS 3.0 四种标准认证协议做一个具体对比: