关于单点登录:如何基于Security实现OIDC单点登录

30次阅读

共计 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

 

扫码关注有惊喜!

正文完
 0