SSO用户统一登录接入文档

1. 目的

本文档主要目的是为用户权限系统进行详细设计和功能模块说明,面向读者是需要接入用户权限系统的后端开发者和开发用户权限系统的开发者。

2. 系统详细设计

交互流程参见下图

sso

2.1 认证中心相关API

1-三方应用检测未登录跳转sso

请求说明

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="}

    

2-登录成功的回调

请求说明

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。

3-获取token相关

请求说明

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
}

    

4-checklogin

请求说明

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":"",
}

    

5-退出登录

请求说明

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",
}