Skip to content

OAuth2

认证协议

我们支持通过 OAuth2 的授权码模式来实现用户身份认证的过程,详见 RFC6749-section-4.1

使用授权码模式,将先通过一次用户的身份认证与授权,经用户确认后方能获得 token

在 OAuth2 协议时,平台已经实现了与学校统一身份认证系统,企业微信的集成对接,并且自动根据环境判断认证方式。因此通过授权码模式对接的应用,在浏览器上访问时,将通过统一身份认证系统认证,在微信/企业微信内打开时,则将自动通过企业微信认证。一次对接即可打通两个平台。

OAuth2 Endpoints

认证流程

当集成身份认证时,采用的即为 OAuth2.0 授权码模式的认证流程,详见[RFC6749-section-4.1,流程大抵如下:

  • a) 用户访问客户端,客户端将用户导向认证服务器。
  • b) 用户进行身份认证,并选择是否给予客户端授权。
  • c) 假设用户给予授权,认证服务器先生成一个授权码(code),并返回给用户,认证服务器将用户导向客户端事先指定的“重定向URI”(redirect uri),同时附上一个授权码(code)。
  • d) 客户端收到授权码,附上早先的“重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
  • e) 认证服务器核对了授权码和重定向URI,确认无误后,向客户端返回访问令牌。
  • f) 客户端可解析令牌中的 id_token 数据获取用户名信息,或者使用令牌中的 access_token 调用用户信息的相关接口,以获得更多用户相关信息。

a-c) 发起认证请求

用户侧发起请求,重定向到认证服务的 Authorization Endpoint(即 https://api.ecnu.edu.cn/oauth2/authorize) ,并携带相关参数

请求参数和示例

参数名是否必填备注
response_type必须是 code
redirect_uri期望的回调地址
scope统一为 ECNU-Basic
client_id所分配的client_id
state随机数,预防 cors 攻击,建议加上
https://api.ecnu.edu.cn/oauth2/authorize?scope=ECNU-Basic&redirect_uri=https://developer.ecnu.edu.cn/playground/authorization_code/callback&response_type=code&client_id=c99********1394d&state=92176092

认证授权

用户会被引导到统一身份认证,完成认证以后会触发授权。

符合以下情况,则该授权页面不会弹出

  • 用户已经授权且记住了授权结果
  • 应用没有申请任何接口权限(即仅通过 id_token 解析用户名,或者仅请求 /oauth2/userinfo 接口获取用户名)
  • 应用被允许无需弹出授权页面

返回参数和示例

参数名备注
code所返回的 code
state请求时附加的随机数,原样带回
https://developer.ecnu.edu.cn/playground/authorization_code/callback?code=c99********1394&state=92176092

d-e) 换取 Token

请求方法

POST

请求地址

https://api.ecnu.edu.cn/oauth2/token

请求参数

参数名是否必填备注
grant_type必须是 authorization_code
client_id所分配的 client_id
client_secret所分配的 client_secret
scope默认 ECNU-Basic
redirect_uri重定向地址,必须和发起请求时的重定向地址一致
code上一步获取到的code

返回参数

参数名类型备注
token_typestringtoken类型
access_tokenstring获得的 token
id_tokenstringjwt 的 id token
expires_innumbertoken 的有效期
scopestring默认为 ECNU-Basci
refresh_toklenstringrefresh token

请求示例

curl -i -X POST -d "code=37*****c077&redirect_uri=https://developer.ecnu.edu.cn/playground/authorization_code/callback&client_id=c99********1394&client_secret=12d***************c54&scope=ECNU-Basic&grant_type=authorization_code" "https://api.ecnu.edu.cn/oauth2/token"

返回示例

json
{
	"access_token": "d14074bc99ac53e2722d29e1792af793",
	"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJkOTZlODQ5MzE1NGRmYWJjIiwiZXhwIjoxNjIzMzA2Njg0LCJpYXQiOjE2MjMyOTk0ODQsImlzcyI6IkVDTlUtQmFzaWMiLCJzdWIiOiIyMDE1MDA3MyJ9.UQdA6RJh6iCxuflCXdaGGO1J2f-LqA7J8v4zFUSKIPZhzhlGZBcDFqYuQ9WGJuRIshuLAeeiLT4Qyhc831Xe5Dv_IK6ROMnU0Fp9q35tvPg4LbAuJkDdLpA74gIifAU-Av7g-3ITdgNNMIerEBpdbZl4YF2U9j8bL4_NjzH-nvKB6J-EFNjLGGyPswlCXiYsBau4Y-7z3GZebxOnBQOcCXd_yRWx5403hl8sSfQMCH6tBMQoZIqbkdsy89q3p2_MCAK46LwuojuQL9E89YD7aBBgw0EkO9dGBv_7Qv2vQpiMsCivhpuOMHzQDnqxNQmXbdlLE2SGX9zrNqhnkMJ7dw",
	"token_type": "Bearer",
	"expires_in": 7200,
	"scope": "ECNU-Basic",
	"refresh_token": "5945d98c447132400033f9305efdb1c5b96d48bb3dca979b269536bf0d0e2732"
}

f) 获取用户信息

获取到 token 以后,客户端再进一步获取用户信息。例如通过解析 id_token 获取用户名。或者请求具体的用户信息接口即可。

身份令牌

我们在身份认证协议中,部分支持了 OpenID Connect 协议。token 中返回的 id_token,身份令牌,也就是 ID Token 是由身份认证服务返回的,包含用户基本信息的 JWT 令牌。

身份令牌的 payload 主要构成部分如下:

json
{
    "aud": "c99909106af1394d", // client_id
    "exp": 1623301919, // 到期时间
    "iat": 1623294719, // 签发时间
    "iss": "ECNU-Basic", // Scope,目前都是 ECNU-Basic
    "sub": "20150073" // 所认证的用户名
}

请求用户信息

OAuth2 服务默认提供了两种风格的 userinfo 接口,以获取最基本的用户信息,其包含以下字段内容。

字段类型说明
userIdstring用户的学号
namestring用户的姓名
vpnEnablednumber用户是否具备 VPN 权限,1 表示具备,0 表示不具备

接口支持 Authorization: Bearer 或者 url query 两种形式的 token 鉴权模式,详见使用令牌调用接口 部分的相关说明。

如需获取更多的信息,则需要申请相关的数据接口

https://api.ecnu.edu.cn/oauth2/userinfo 将提供一个带层级,含错误码的用户信息接口,其返回示例如下:

json
{
	"errCode": 0,
	"errMsg": "success",
	"requestId": "d1e51040-415e-4fe7-9a70-12ccb0bece21",
	"data": {
		"userId": "20****3",
		"name": "**",
		"vpnEnabled": 1
	}
}

https://api.ecnu.edu.cn/oauth2/userinfo/flat 将提供一个扁平的用户信息接口,其返回示例如下:

json
{
		"userId": "20****3",
		"name": "**",
		"vpnEnabled": 1
}

注销

应用注销时,可以通过访问 https://api.ecnu.edu.cn/user/logout?redirect_uri=https://apphost/xxxx 实现单点登录的注销。接口将自动注销 OAuth2 服务与 CAS 服务的会话,并重定向到期望的回调地址 redirect_uri 上。

如果 redirect_uri 不存在,则用户注销后会跳转至 https://developer.ecnu.edu.cn/

回调地址 redirect_uri 的域名,必须与该应用授权的域名一致,否则将跳转至默认页面 https://developer.ecnu.edu.cn/

会话与用户授权管理

授权服务器提供 access_token 的令牌签发,并确保令牌签发的过程中有用户的认证授权确认。会话应由应用端自行维护管理。尽管我们在授权码模式中,集成了 CAS 认证协议,并与学校其他 CAS 集成应用相兼容并支持 SSO。但 SSO 的会话仍然应该与应用本身的会话相独立,已经完成认证的用户应该由应用本身会话管理,避免不必要的认证触发行为。

当应用的会话有效期比较长时,可能需要刷新 token 以重新获取用户信息,此时可以使用 refresh_token 来刷新 token。refresh_token 的有效期为1个月,因此应用的会话有效期不应超过1个月,即每个月至少用户需要登录一次,否则用户信息可能无法更新。

授权码模式的应用,可以申请用户授权状态管理的接口,从而自行修改或更新用户的授权状态。详见 应用管理 中用户授权状态相关的接口。