共计 3177 个字符,预计需要花费 8 分钟才能阅读完成。
一、阐明
本文次要是给大家介绍 OIDC
的外围概念以及如何通过对 Spring Security
的受权码模式进行扩大来实现 OIDC 的单点登录。
OIDC
是 OpenID Connect 的简称,OIDC=(Identity, Authentication) + OAuth 2.0。它在 OAuth2
上构建了一个身份层,是一个基于 OAuth2 协定的身份认证标准协议。咱们都晓得 OAuth2 是一个受权协定,它无奈提供欠缺的身份认证性能,OIDC 应用 OAuth2 的受权服务器来为第三方客户端提供用户的身份认证,并把对应的身份认证信息传递给客户端,且齐全兼容 OAuth2。
PS:了解 OIDC 的前提是须要了解 OAuth2,如果对 OAuth2 的单点登录的原理和流程还不太理解的能够看我之前的文章《Spring Security 基于 Oauth2 的 SSO 单点登录怎么做?一个注解搞定》
二、OIDC 外围概念
OAuth2 提供了 Access Token
来解决受权第三方 客户端
拜访受爱护资源的问题;OIDC 在这个根底上提供了 ID Token
来解决第三方客户端标识用户身份认证的问题。OIDC 的外围在于 OAuth2 的受权流程中,一并提供用户的身份认证信息 ID Token
给到第三方 客户端
,ID Token
应用 JWT
格局来包装。
OIDC 协定受权返回示例:
{
"resp_code": 200,
"resp_msg": "ok",
"datas": {
"access_token": "d1186597-aeb4-4214-b176-08ec09b1f1ed",
"token_type": "bearer",
"refresh_token": "37fd65d8-f017-4b5a-9975-22b3067fb30b",
"expires_in": 3599,
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwOi8vemx0MjAwMC5jbiIsImlhdCI6MTYyMTY5NjU4MjYxNSwiZXhwIjoxNjIxNjk2NjQyNjE1LCJzdWIiOiIxIiwibmFtZSI6IueuoeeQhuWRmCIsImxvZ2luX25hbWUiOiJhZG1pbiIsInBpY3R1cmUiOiJodHRwOi8vcGtxdG1uMHAxLmJrdC5jbG91ZGRuLmNvbS_lpLTlg48ucG5nIiwiYXVkIjoiYXBwIiwibm9uY2UiOiJ0NDlicGcifQ.UhsJpHYMWRmny45K0CygXeaASFawqtP2-zgWPDnn0XiBJ6yeiNo5QAwerjf9NFP1YBxuobRUzzhkzRikWGwzramNG9na0NPi4yUQjPNZitX1JzlIA8XSq4LNsuPKO7hS1ALqqiAEHS3oUqKAsjuE-ygt0fN9iVj2LyL3-GFpql0UAFIHhew_J7yIpR14snSh3iLVTmSWNknGu2boDvyO5LWonnUjkNB3XSGD0ukI3UEEFXBJWyOD9rPqfTDOy0sTG_-9wjDEV0WbtJf4FyfO3hPu--bwtM_U0kxRbfLnOujFXyVUStiCKG45wg7iI4Du2lamPJoJCplwjHKWdPc6Zw"
}
}
能够看到与一般的 OAuth2 相比返回的信息中除了有 access_token 之外还多出了 id_token 属性。
三、什么是 ID Token
ID Token 是一个平安令牌,由受权服务器提供的蕴含用户信息的 JWT 格局的数据结构,得益于 JWT(JSON Web Token)的自蕴含性,紧凑性以及防篡改机制,使得 ID Token 能够平安的传递给第三方客户端程序并且容易被验证。
id_token 蕴含以下内容:
{
"iss": "http://zlt2000.cn",
"iat": 1621696582615,
"exp": 1621696642615,
"sub": "1",
"name": "管理员",
"login_name": "admin",
"picture": "http://xxx/ 头像.png",
"aud": "app",
"nonce": "t49bpg"
}
- iss:令牌颁发者
- iat:令牌颁发工夫戳
- exp:令牌过期工夫戳
- sub:用户 id
- name:用户姓名
- login_name:用户登录名
- picture:用户头像
- aud:令牌接收者,OAuth 利用 ID
- nonce:随机字符串,用来避免重放攻打
3.1. 与 JWT 的 Access Token 区别
是否能够间接应用 JWT 形式的 Access Token 并在 Payload 中退出用户信息来代替 ID Token 呢?
尽管在 Access Token 中能够退出用户的信息,并且是防篡改的,然而用户的每次申请都须要携带着 Access Token,这样岂但减少了带宽,而且很容易泄露用户的信息。
3.2. 与 UserInfo 端点的区别
通常 OIDC 协定都须要另外提供了一个 Get /userinfo
的 Endpoint,须要通过 Access Token 调用该 Endpoint 来获取具体的用户信息,这个办法和 ID Token 同样都能够获取用户信息,那两者有什么区别呢?
相比拟于 Get /userinfo
的接口应用 ID Token 能够缩小近程 API 调用的额定开销;应用那个次要是看 需要,当你只须要获取用户的根本信息间接应用 ID Token 就能够了,并不需要每次都通过 Access Token 去调用 Get /userinfo
获取具体的用户信息。
四、OIDC 单点登录流程
上面咱们看一个 OIDC 协定罕用的场景,就是具备 独立用户体系 零碎间的单点登录,意思指的是用户数据并不是对立共用的,而是每个零碎都领有本人独立的用户数据,所以流程最初减少了一步 主动注册用户。
大部分的流程与 OAuth2 的受权码模式雷同这里就不多讲述了,其中上面两个步骤须要阐明一下:
- 解析 ID Token 的公钥能够是事后提供给第三方零碎也能够是提供接口获取。
- 主动注册用户 指的是第一次单点登录的时候,因为用户信息不存在须要在本零碎中生成该用户数据;例如你从未在 CSDN 中注册也能够应用微信来登录该网站。
五、Spring Security 实现
先说一下扩大最终的指标是须要达到以下成果:
- 受权码模式:
/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code
- OIDC 模式:
/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code id_token
指标是要通过在 response_type 中的传值来管制是否应用 OIDC 模式,如果应用则在 response_type 中减少 id_token 的值。
因为须要在 OAuth2 返回的内容中增加 ID Token 属性,所以实现这个扩大的要害就是须要通过 Security 的 TokenEnhancer
来为 Token 增加自定义字段;
定义 TokenEnhancer 的 Bean 来扩大 Token:
通过受权的 response_type 参数来判断是否须要生成 id_token。
生成 ID Token 的 JWT:
PS:下面只列出了局部要害代码,残缺代码请通过上面的 demo 地址去下载。
六、残缺的 demo 下载地址
https://gitee.com/zlt2000/microservices-platform/tree/master/zlt-demo/sso-demo/oidc-sso
扫码关注有惊喜!