本文档主要目的是为用户权限系统进行详细设计和功能模块说明,面向读者是需要接入用户权限系统的后端开发者和开发用户权限系统的开发者。
交互流程参见下图
请求说明
method | GET |
host | sso auth域名 |
url | /sso/auth |
格式 | |
提供方 | sso auth |
使用方 | 三方应用 |
备注 | sso auth人员关注即可 |
备注 | 在返回值之前有很多sso auth自用的中间302跳转请求,三方应用人员不用关心,最终正确结果是跳转 三方应用回调带上参数 |
请求header
参数 | 参数类型 | 注释 |
---|
请求参数
参数 | 参数类型 | 注释 |
---|---|---|
client_id | string | 应用ID,必须 |
redirect_uri | string | 回调地址不带参数,正是 三方应用回调,必须 |
response_type | string | 所需认证类型,授权码为code,必须 |
scope | string | 授权范围,加号连接的数组字符串,必须,openid+email+groups+profile+offline_access |
state | string | 状态码,固定值oauth,必须 |
refer | string | 透传的应用域名页面链接,一般为三方应用当前页面地址,非必须 |
请求参数示例:
/auth?client_id=10052&redirect_uri={三方应用回调}&refer={三方应用页面原地址}&response_type=code&
scope=openid+email+groups+profile+offline_access
&state=oauth
返回值
sso登录界面;涉及登录操作的中间302跳转处理如下;登录成功浏览器前端自动根据sso服务端返回的json(状态码302和跳转链接)跳转 三方应用回调
中间处理三选一,1是目前登录页面直接使用的。
1. /auth/{connector}/login?state={auth requestID}&username=&password= # POST application/x-www-form-urlencoded 验证密码并生成离线会话并在sso域名种下cookie和返回数据 {"code":302,"msg":"","data":{"location":"XXXX?code={授权码}&state=oauth&refer="}} 或者 {"code":302,"location":"XXXX?code={授权码}&state=oauth&refer="} 浏览器前端进行跳转
2. /callback/{connector}?state={auth requestID} # GET 根据已登录的auth request生成离线会话
或者
/callback/{connector}?RelayState={auth requestID} # POST application/x-www-form-urlencoded 根据已登录的auth request生成离线会话
# 返回数据 {"code":302,"location":"XXXX?code={授权码}&state=oauth&refer="}
3. /approval?req={auth requestID} # GET 根据已登录的auth request获取302跳转[三方应用回调](#2-登录成功的回调)
或者
/approval?req={auth requestID}&approval=approve # POST 根据已登录的auth request获取302跳转[三方应用回调](#2-登录成功的回调)
# 返回数据 {"code":302,"location":"XXXX?code={授权码}&state=oauth&refer="}
请求说明
method | GET |
host | 三方应用域名 |
url | 开发实现和应用配置一致即可 |
格式 | |
提供方 | 三方应用 |
使用方 | sso auth |
备注 | 该请求使用授权码调用 sso auth的token接口获取token,三方应用需要关注 |
请求header
参数 | 参数类型 | 注释 |
---|
请求参数
参数 | 参数类型 | 注释 |
---|---|---|
code | string | 授权码,必须 |
refer | string | 透传的应用域名页面链接,非必须 |
state | string | 状态码,固定值oauth |
请求参数示例:
code={授权码}&state=oauth&refer=XXXX
返回值
refer存在数据,则重定向到该地址,不存在则自己决定跳入三方应用域名的页面;并向三方应用域名种cookie。
请求说明
method | POST |
host | sso auth域名 |
url | /sso/token |
格式 | application/x-www-form-urlencoded |
提供方 | sso auth |
使用方 | 三方应用 |
备注 | 获取access token,三方应用需要关注 |
请求header
参数 | 参数类型 | 注释 |
---|---|---|
Authorization | string | "Basic " + base64(clientID + ":" + clientSecret) |
请求参数
参数 | 参数类型 | 注释 |
---|---|---|
grant_type | string | authorization_code/refresh_token/password,必须 |
code | string | 授权码,通过 回调获取的授权码,authorization_code的必须参数,非必须 |
redirect_uri | string | 重定向链接,authorization_code的必须参数,非必须 |
scope | string | 授权范围,refresh_token和password的必须参数,非必须 |
refresh_token | string | 刷新token,refresh_token的必须参数,非必须 |
nonce | string | 随机码,password的必须参数,非必须 |
username | string | 用户名,password的必须参数,非必须 |
password | string | 登录密码,password的必须参数,非必须 |
请求参数示例:
授权码模式
grant_type=authorization_code&code=&redirect_uri=
refresh模式
grant_type=refresh_token&scope=&refresh_token=
password模式
grant_type=password&nonce=&scope=&username=&password=
返回值
返回字段 | 返回字段类型 | 注释 |
---|---|---|
access_token | string | access token,必须 |
token_type | string | token类型,必须,固定值bearer |
expires_in | int | 过期时间,还有多少秒,必须 |
refresh_token | string | refresh token,非必须 |
id_token | string | id token,包含透传的refer链接,必须 |
返回值示例:
{
"access_token":"",
"token_type":"",
"expires_in":3600,
"refresh_token":"",
"id_token":"XXXX.YYYYYYY.ZZZZZ",
}
JWT解析id_token
func parseJWT(idToken string) ([]byte, error) {
parts := strings.Split(idToken, ".")
if len(parts) < 2 {
return nil, fmt.Errorf("oidc: malformed jwt, expected 3 parts got %d", len(parts))
}
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
if err != nil {
return nil, fmt.Errorf("oidc: malformed jwt payload: %v", err)
}
println("raw:", string(payload))
return payload, nil
}
parseJWT("XXXX.YYYYYYY.ZZZZZ")
解析结果取用token_id给 checklogin接口使用,exp是过期时间戳,iat是颁发时间戳
{
"iss": "https://portal.dtwin.tencent.com/sso",
"sub": "XXXXXXXXXXXXXXXXXXXXXXXX",
"aud": [
"XXXXX"
],
"exp": 1688553916,
"iat": 1688467516,
"at_hash": "XXXXXXXXXXXXXXX",
"email": "XXXXXXX@gmail.com",
"email_verified": false,
"name": "XXXXXXXXXXXXXX",
"preferred_username": "",
"federated_claims": null,
"token_id": "XXXXXXXXXXXXXXXXXX",
"refer": "",
"userid": "XXXXXXXXXXXXXXXXXX",
"usertype": "2",
"remember": "true",
"remind": false
}
请求说明
method | POST |
host | sso auth域名 |
url | /sso/checklogin |
格式 | application/x-www-form-urlencoded |
提供方 | sso auth |
使用方 | 三方应用 |
备注 | 检查登录态使用,很重要,三方应用需要关注 |
请求header
参数 | 参数类型 | 注释 |
---|
请求参数
参数 | 参数类型 | 注释 |
---|---|---|
code | string | 通过 token接口获取的token_id,必须 |
clientId | string | 配置的应用ID,必须 |
请求参数示例:
code={授权码}&clientId=10234
返回值
返回字段 | 返回字段类型 | 注释 |
---|---|---|
tokenId | string | access token,必须 |
userId | string | 用户ID,必须, |
userType | string | 用户角色类型,1-超级管理员;2-1号管理员;3-普通管理员;99-普通用户,非必须;当租户ID非空才有意义 |
tenantId | string | 租户ID,非必须 |
teamId | string | 工作空间ID,非必须 |
username | string | 用户姓名 |
name | string | 用户名 |
roles | list | 角色列表,非必须 |
roles. roleId | string | 角色ID,必须 |
roles. roleName | string | 角色名,必须 |
funcRes | list | 功能列表,非必须 |
funcRes. resId | string | 待补充,非必须 |
funcRes. resType | string | 待补充,非必须 |
funcRes. resKey | string | 待补充,非必须 |
funcRes. resName | string | 待补充,非必须 |
funcRes. resUrl | string | 待补充,非必须 |
funcRes. resOrder | int | 待补充,非必须 |
funcRes. resSubKey | string | 待补充,非必须 |
funcRes. parentId | string | 待补充,非必须 |
funcRes. iconPath | string | 待补充,非必须 |
funcRes. serviceId | string | 待补充,非必须 |
返回值示例:
{
"username":"",
"name":"",
"tokenId":"",
"userId":"",
"userType":"",
"roles":[{
"roleId":"",
"roleName":"",
}],
"funcRes":[{
"resId":"",
"resName":"",
"parentId":"",
"resType":"",
"resKey":"",
"resUrl":"",
"resOrder":0,
"resSubKey":"",
"iconPath":"",
"serviceId":"",
}],
"tenantId":"",
"teamId":"",
}
请求说明
method | POST |
host | sso auth域名 |
url | /sso/logout |
格式 | application/x-www-form-urlencoded |
提供方 | sso auth |
使用方 | 三方应用 |
备注 | 三方应用需要关注 |
请求header
参数 | 参数类型 | 注释 |
---|
请求参数
参数 | 参数类型 | 注释 |
---|---|---|
clientId | string | 应用ID,必须 |
code | string | 通过 token接口获取的token_id,必须 |
请求参数示例:
签名模式
code=&clientId=
返回值
返回字段 | 返回字段类型 | 注释 |
---|---|---|
msg | string | 信息,必须,固定值success |
返回值示例:
{
"msg":"success",
}