SSO 单点登录
基于OAuth2实现的统一认证
OAuth2 实质是为第三方应用颁发一个具有时效性的Token令牌,使其他服务或第三方应用能够通过令牌获取相关资源。 常见的场景: 比如进入某个网站没有账号信息, 但可以通过QQ、微信、支付宝等
账号进行登陆, 在这个登陆过程中采用的就是Oauth2协议;OAUTH2不仅支持认证,还具备授权功能, 比如通过QQ登录获取用户头像,基本资料等。
OAuth2角色
resource owner : 资源所有者,具备访问该资源的实体, 如果是某个人, 被称为end-user。
resources server: 资源服务器,受保护的资源服务器, 具备提供资源能力, 如订单服务, 商品服务等。
client: 客户端,这并不是指用户, 而是对资源服务器发起请求的应用程序,比如前后分离项目,前端服务访问管理接口, 访问后台业务功能接口。
authorization server: 授权服务器, 能够给客户端颁发令牌, 这个就是我们上面所讲的统一认证授权服务器。
user-agent: 用户代理, 作为资源所有者与客户端沟通的工具, 比如APP, 浏览器等。
协议流程
- 授权码模式
- 隐式/简化授权模式
- 密码模式
- 客户端模式
OAuth2授权码模式
不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。
A)用户访问客户端,后者将前者导向授权服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,授权服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向授权服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)授权服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refreshtoken)。
隐式/简化模式
OIDC
我老东家内部使用的是OIDC 这里主要学习一下OIDC的逻辑
什么是OIDC
OIDC 的全称是 OpenID Connect,是一套基于 OAuth 2.0 的认证 + 授权协议,用于用户身份认证,将用户数据安全地暴露给第三方。
OIDC 与 OAuth 2.0 有何不同?
OAuth 2.0 是用于授权的行业标准协议。OAuth 2.0 致力于简化客户端开发人员的工作,同时为Web 应用程序,桌面应用程序,移动电话和物联网设备提供特定的授权流程。
以上是 OAuth 2.0 的官方定义。我们举一个实际的例子,你在登录京东的时候,会发现在京东的登录框中有使用 QQ 登录、使用 QQ 登录的按钮,这些地方就是 OAuth 2.0 协议的用武之地。京东希望从 QQ 获取你的 QQ 用户数据,从而完成在京东的注册,这就需要数据的主人——你的授权。完成授权之后, QQ 会给京东一个 access_token,京东携带这个凭证,就能以你的名义,以及你授予此网站的权限(例如你授权京东能够访问你的个人信息而不是转账能力),访问你在 QQ 服务器上的数据,从而获取你的信息,在此过程中,你无须告诉京东你的 QQ 账号和密码,你输入账密信息的时候,是在腾讯的服务器完成的认证。
OIDC 与 OAuth 2.0 相比,多了认证的能力。不但能够返回用户的 access_token,让第三方通过 access_token 调用用户授权过的接口(用户授权),还可以返回用户的 id_token,第三方可以将 id_token 用作用户身份标识(用户认证)。
回到刚才的例子,京东获取到 QQ 颁发的 access_token(是一个随机字符串)之后确实能够获取到你的信息,但是如果不借助其他手段,是不具备用户身份认证功能的。而在 OIDC 协议中,获取 access_token 的同时,会返回一个 JWT 格式的 id_token,可直接用作身份标识,供第三方确认用户身份。
JWT Token 是这个样子的:
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
格式为“点分 base64 编码”,一共三段,第一部分叫作头部(JOSE Header),第二部分叫作荷载(Payload),第三部分叫作签名(Signature)。其中的签名根据头部、荷载和一个密钥计算得出,不可伪造。
base64 解码之后是这样子的:
{"typ":"JWT", "alg":"HS256"}.{"iss":"joe", "exp":1300819380, "http://example.com/is_root":true}.<
OIDC的授权码模式
- 第三方应用访问认证服务器的授权链接。(用户在OA网站登录框点击使用 QQ 登录)
- 用户与认证服务器完成身份认证。(浏览器跳转到 QQ 授权页面,用户输入 QQ 号和密码)
- 认证服务器向第三方应用返回授权码 code。(QQ 服务器将用户的浏览器重定向,将授权码发送到京东服务器)
- 第三方应用携带授权码访问认证服务器的 token 接口。(京东服务器携带授权码与 QQ 服务器交互)
- 认证服务器返回 access_token 和 id_token 给第三方应用。(QQ 服务器返回 access_token 和 id_token 给京东服务器)
OIDC认证时候相关Token解释
OIDC 认证时会签发两种 Token,一类叫 id_token,还有一类叫 access_token。
- id_token 是用户身份的凭证,只起到判定用户身份的作用。
id_token 示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZTQ5NjBkZmJkOTE1OGZiODQ0OTAzYTkiLCJ
北森的id_token生成规则为: rsa256
生成JwtPayload对象
iss 参数:Issuer Identifier:必须。提供认证信息者的唯一标识。一般是一个https的url(不包含querystring和fragment部分)
sub: 用户唯一标识
aud: OAuth2的client_id 这个传入北森的tendID
iat: 构建时间
exp: 过期时间 15分钟
cls: 扩展信息 包含uty: 一般为id
appid :100
url_type pc还是移动端
isv_type 0
vsn版本号 1
OIDC的隐式/简化模式
- 第三方应用访问认证服务器的授权链接。(用户在京东网站登录框点击使用 QQ 登录)
- 用户与认证服务器完成身份认证。(浏览器跳转到 QQ 授权页面,用户输入 QQ 号和密码)
- 认证服务器向第三方应用返回 id_token 和 access_token。(QQ 服务器将用户的浏览器重定向,将 id_token access_token 发送到京东前端页面)
隐式模式比授权码模式简单,经常用于将 id_token、access_token 直接返回到前端,方便前端直接存储 id_token 用于证明用户身份。也需要前端自行将 access_token 发回后端,后端用于获取用户的详细信息,这增加了暴露 access_token 的风险。隐式模式不支持返回 refresh_token,即不能从后端刷新 access_token,登录一旦过期需要用户重新登录。
评论区