# 授权码模式

# 概述

​ OIDC是OpenID Connect的缩写,OIDC=Identity,Authentication+OAuth2.0。GOSP的认证中心基于OIDC实现。

​ 授权码模式是一种混合模式,是目前功能最完整、流程最严密的授权模式。

​ 它主要分为两个步骤:获取授权码Code和获取令牌access_token。

(A) 用户访问业务系统,业务系统判断用户是否登录,若未登录,将业务系统导向到认证中心。

(B)用户输入账号密码给认证系统。

(C)假设用户认证通过,认证服务器将用户导向业务系统事先指定的"重定向URI"(redirection URI),同时附上一个授权码“Authorization Code”。

(D)业务系统收到授权码,附上早先的"重定向URI",向认证服务器申请令牌access_token。这一步是在业务系统的后台的服务器上完成的,对用户不可见。

(E)认证服务器核对了授权码和重定向URI,确认无误后,向业务系统发放令牌。

具体过程如下图所示: 认证流程

# 业务系统接入场景说明

# 登录页面

用户通过访问业务系统,业务系统302跳转到认证中心登录页面。

# 获取授权码Code

在认证系统的登录页面内输入用户名、密码等凭证信息后,系统调用认证中心的”获取Code“服务,获取“Authorization Code”,并且携带获取到的code重定向到该服务接口中定义的重定向URL。 此时,业务系统应在需要登录时重定向到认证中心的登录页面,并将redirect_uri参数指向登陆后的业务系统的后续处理页面。

# 获取令牌access_token

业务系统根据先前获取的“Authorization Code”,调用认证中心的”获取Token“服务,获取令牌access_token。 业务系统在access_token的有效期内,可以带着access_token跟GLINK进行交互,完成GLINK系统提供的组织、用户、角色、权限、流程(*)等业务功能。

# 更新令牌access_token

建议业务系统将access_token存放在用户相关的缓存内,一旦access_token过期,业务系统需使用“获取Token"服务获取一个新的访问令牌。

# 获取用户信息

当业务系统需要根据access_token获取用户信息时,可调用本接口获取GLINK平台用户中心的相关信息。

# 用户登出

当业务系统用户退出本系统时,可调用本接口实现身份注销。

# 校验token

当业务系统发起请求时,通过此接口验证token有效性。

# 撤销token

强制使token过期。

# 接口说明

# 获取授权码Code

# 请求路径:

/nepoch-oidc/authorize?response_type={response_type}&scope={scope}&client_id= {client_id}&state={state}&redirect_uri={redirect_uri}

# 请求方法:

GET

# 请求参数:

参数 是否必须 说明
response_type 或 grant_type 授权模式,值固定为 "code"
client_id 客户端ID,由授权中心提供(可向平台人员索取)
redirect_uri 重定向Uri,需进行URL编码,需要是已注册的回调地址。
scope 值自定义选择一个或多个:openid、email、offline_access、profile"
state 可以指定任意值,认证中心会原封不动地返回这个值

# 返回信息:

名称 类型 字段名 描述
授权码 String code
上一步的状态码 String state 防止CSRF, XSRF

# 示例

  • 请求范例:
GET http://oidc.glink.glkyun.com/nepoch-oidc/authorize?response_type=code&scope=openid email offline_access profile&client_id=test01&state=xyz&redirect_uri=https://client.example.com/cb 
1
  • 响应范例:
https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
1

# 获取/更新令牌accessToken

# 请求路径:

/nepoch-oidc/token

# 请求方法:

POST

# 请求参数:

Content-Type: application/x-www-form-urlencoded

参数 是否必须 说明
grant_type 授权模式,第一次获取时为 "authorization_code" 或 "code",更新令牌时为"refresh_token"
code 条件 上一步获得的授权码,当授权模式为第一次获取"authorization_code"时必填。
refresh_token 条件 刷新token,当授权模式为刷新令牌"refresh_token"时必填。
client_id 客户端ID,由授权中心提供(可向平台人员索取)
client_secret 客户端SECRET,由授权中心提供(可向平台人员索取)
redirect_uri 重定向URI,且必须与上一步的该参数值保持一致
scope 条件 申请的权限范围,不可以超出上一次申请的范围。如果省略该参数,则与上一次scope一致。比如" openid email offline_access profile"

# 返回信息:

名称 类型 字段名
access_token String 请求token
token_type String token类型
refresh_token String 刷新token
expires_in Long 过期时间
scope String 授权范围
id_token String 身份信息

# 示例

  • 请求范例:
POST  /nepoch-oidc/token
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
{
    "grant_type":"authorization_code",,
    "code": "SplxlOBeZQQYbYS6WxSbIA",
    "client_id": "GONGWEN",
    "client_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "redirect_uri": "https://client.example.com/cb",
    "scope": "openid email offline_access profile"
}
1
2
3
4
5
6
7
8
9
10
11
  • 响应范例:
{
    "access_token": "eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImF6cCI6ImdsaW5rIiwiaXNzIjoiaHR0cDpcL1wvb2lkYy5nbGluay5nbGt5dW4uY29tXC9uZXBvY2gtb2lkY1wvIiwiZXhwIjoxNjE1OTY2MzQwLCJpYXQiOjE2MTU5NjI3NDAsImp0aSI6IjhlNzZmZWYzLWY2YTktNGI0Yy04ZWVkLTg5ZTJjMTExNWYyZCJ9.TYbUmuhSQfiULjkb0vNLTwNCe4gSMjn_U_UlkH7AK6LaC7tO7tzrNL_IsfabzXCRWj3MG8z1jGIaTWbG0D0892HdTIft7abtvXNGcUUgyGonjkg6_AUr9rLzhyYIr9M8ctK6L6TK-8qnKva8mqfYIWlFIrbtjCTVMiPBEp6fnjk-HtFiL5mgJwkmm44qum-8tDw66WeAJ09nxGgtBNhVjqtKa-L74R0C6dSTQc5qpiszgdQ6vpd3VrY7P6j7qgQ63W2T9_yb24TigmhSQWOopVlbIDI5_Mou6koQBPTuebYxok3Jukcr1q763biwzmiMvhvHXMCn4eVyf9MOxfKm4Q",
    "token_type": "Bearer",
    "refresh_token": "eyJhbGciOiJub25lIn0.eyJqdGkiOiJiOTI5YTNlZC0yMTU4LTQ0ZTMtYTY2MC00NzAyODc3M2VlMWIifQ.",
    "expires_in": 3599,
    "scope": "openid offline_access profile email",
    "id_token": "eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJhZG1pbiIsImF1ZCI6ImdsaW5rIiwiYXV0aF90aW1lIjoxNjE1OTYyMjMyLCJraWQiOiJyc2ExIiwiaXNzIjoiaHR0cDpcL1wvb2lkYy5nbGluay5nbGt5dW4uY29tXC9uZXBvY2gtb2lkY1wvIiwiZXhwIjoxNjE1OTYzMzQwLCJpYXQiOjE2MTU5NjI3NDAsImp0aSI6IjU0NmM2MDIwLTdiYmUtNDFmYi05Yzk0LWNjNjAyNDQ5NThmZSJ9.ChT8HLgtOSW_biP0HV0nf0p0d9R69YFV5I8ZnFPglk2XBsyDQyiGinu6aV8ModnXmQsaRPEiIExMXgxOJLwiRvrju3xaRG6A4-_h5dl2JJYpFEYG3ALwuchs_dBqMFRSqZCMbwaksXkrn9Uj681jcZ6vUAGbNpCCk7dBUU0ZUCnP8DqWP45UIjg_bF4y18qBkedaMZvnXjHrRXYCy01Gk5Wyj_qzE8fj6JR8iDm8L1_Pj_kWblVLxBng7BdBwcV0ZqiUpfoqc-Nqe51gg2nASnYwmhq4ITODnvboUaDrOdc4JC-vRE7krkHWuA_NRWLROapJj3Ru3wP3CtDLi_4BDg"
}
1
2
3
4
5
6
7
8

# 获取用户信息

业务系统可以根据access_token获取用户基本信息。

# 请求路径:

/nepoch-oidc/userinfo

# 请求方法:

GET

# 请求参数:

Authorization:Bearer {access_token}

参数 是否必须 说明
access_token 请求token

# 返回信息:

名称 类型 字段名
sub String 用户登录账号
name String 姓名
userId String 用户id
account String 账号
email String 邮箱
mobilephone String 手机号
sex int 性别

# 示例

  • 请求范例:
GET /nepoch-oidc/userinfo HTTP/1.1
Host: server.example.com
Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW
1
2
3
  • 响应范例:
 HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 {
	"sub": "admin",
	"name": "管理员",
	"email": "540381107@qq.com",
	"userId": "1",
	"account": "admin",
	"subjectid": "1",
	"username": "管理员",
	"mobilephone": "18392387159",
	"code": "admin",
	"sex": 1,
	"deptid": " ",
	"deptname": " ",
	"alias": "null"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 用户登出

实现身份认证注销。

# 请求路径:

/nepoch-oidc/endsession?post_logout_redirect_uri={post_logout_redirect_uri}&id_token={id_token}

# 请求方法:

GET

# 请求参数:

参数 是否必须 说明
id_token 业务系统从认证中心获取的原始id_token,参见/nepoch-oidc/token接口的返回字段说明
post_logout_redirect_uri 注销跳转地址

# 返回信息:

跳转到post_logout_redirect_uri的地址

# 请求范例:

GET 
nepoch-oidc/endsession?post_logout_redirect_uri=https://www.baidu.com&id_token_hint=eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI5MDM0Mi5BU0RGSldGQSIsImF1ZCI6ImxpdXpoYW8iLCJraWQiOiJyc2ExIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL25lcG9jaC1vaWRjXC8iLCJleHAiOjE2MTQ1ODg1OTAsImlhdCI6MTYxNDU4Nzk5MCwianRpIjoiMWJlZmM5ZGItM2M0Yy00MmYyLTkwMzUtNjA1YmI1YjI0Y2RhIn0.MpFuRMoi5SMhrSNvKaLoDce42ewT4Ltr7BKBPCcLix47qdOJKWKnCpcgetYGKQjQUAhzLM9K5EMGJeyrHNwR09A1er_XtR8Kwo7E-6_duUyfa-g07GpM7cnt-Zv6iKuxbyjdH3dDP2AgxljbF3B-zDEOnxc_4w_0fpOI7cXHkS2HoE7u0koRX15_-LWrDVi9WnihMqcGx0xYN-rKbPz6HxKJy2AfJ5xJsi_T7J5m2DvpYyMPtSxB6mI7_wd15fnfYxfgdWgX1ksGuq8MBAYPVIBE3LVg6Er6Q8ce1wJ_3gIfq9f3JGw14q9GAz_4fOuOFx8qISVWqyUHhDk0RhcmyQ
1
2

# 示例

  • 响应范例:
跳转到 https://www.baidu.com
1

# 校验token

校验token

# 请求路径:

/nepoch-oidc/jwk

# 请求方法:

GET

# 请求头参数:

Authorization:Bearer {access_token}

参数 是否必须 说明
access_token 请求token

# 请求范例:

GET 
nepoch-oidc/jwk
1
2

# 示例

  • 校验通过响应范例:
{
	"keys": [
		{
			"kty": "RSA",
			"e": "AQAB",
			"kid": "rsa1",
			"alg": "RS256",
			"n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw"
		}
	]
}
1
2
3
4
5
6
7
8
9
10
11
  • 校验不通过响应范例
{
	"error": "invalid_token",
	"error_description": "Invalid access token: eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJyempyIiwi3lzdGVtSWQiOiJudWxsIiwiYXpwIjoicnpqciIsImlzcyI6Imh0dHA6XC9cL29pZGMuZ2xpbmsuZ2xreXVuLmNvbVwvbmVwb2NoLW9pZGNcLyIsImV4cCI6MTY2MjYzMzcxNSwiaWF0IjoxNjYyNjMwMTE3LCJqdGkiOiIyZWM1Yzc2NC1mMmY1LTQxMjgtYTQwNS0zMDIzOTc5MTlkZmUifQ.UJQYNKOmquNFCrEoSRPpTwW3DMl9yHzRTeKg89VsL0ohu6j7dzEyrYrP4gtG-NtTFdmc38O9M8Cv-MZIu0Ha_Uc6-QAQSreEN-eyY9j9dnh1ILH40z5yld4iDzeBMHWcXtI1GnXi67eXp6yUckz-BqdgZ5M34dr_Ccx52TMYwYpa9d8onvRdyc1icKOPmg5BKMLCgUF9q56oGCATQa-tWl0qKg0pxfYevjj7mhJhtXEicqnqsOU8YirD295Dpl8R0L3erx0g_iD2yZGd8Xc4MFTXGN8aqxXfxocwSydZ9P8PJszy-ix0qNd5trY812KMMm7HrU4jED3d1wahw8Ao-Q"
}
1
2
3
4

# 撤销token

撤销token

# 请求路径:

/nepoch-oidc/revoke

# 请求方法:

GET

# 请求头

"Authorization": "Basic client-id:client-secret"
1

# 请求参数:body

参数 是否必须 说明
token 请求token

# 响应示例

  • 撤销成功响应范例:
状态码 200
1
  • 撤销失败响应范例
状态码 401
{
	"error": "unauthorized",
	"error_description": "Bad credentials"
}
1
2
3
4
5