-
产品及方案 产品及方案
-
数据驱动型组织通过体系化的方法构建全域数据能力,实现数据驱动运营,重塑组织生产力
- 行业方案
- 典型方案
- 产品
-
数据驱动型组织
- 服务与支持
- 社区
- 合作伙伴
- 关于爱数
请选择咨询类型
扫码关注
爱数技术支持中心公众号
我们将在 24 小时之内联系你。
业务系统和 AnyShare 7 对接,调用 OpenDoc API 时需要在请求头中加入访问令牌才能得到正确的响应,所以需要提供一份认证指南。该指南以生成业务系统使用的访问令牌为目的。
Access_token: 访问令牌,调用 OpenDoc API 需要加入 "Authorization: Bearer Access_token" Header
Client_id: 客户端 id,用于识别业务系统,建议每个业务系统使用一个单独的 Client_id
Client_secret: 客户端密钥,和 Client_id 一一对应,统一生成
JWT: 即 JSON Web Token,网络应用环境间传递声明而执行的一种基于json的开放标准
Plugin_id: 插件 id,AnyShare 第三方认证插件 id
Plugin_secret: 插件密钥,用于 JWT 签名
As_code: 用于换取 Access_token 的临时密钥
AnyShare 7.0.1以上版本
已通过爱数集成开发工程师定制第三方认证插件
定制的认证插件主要完成验证 JWT 的过程,对于有能力的服务商,可以自行开发插件
这一步应由管理员操作
登录 AnyShare 8000 控制台,可以在第三方配置插件界面获取 Plugin_id 和 Plugin_secret:
这一步可以由管理员(推荐)或业务系统操作,生成的client_id和redirect_uris可以保存在配置文件中,多次使用。
可以使用 http 请求按以下方式生成业务系统客户端:
URL: https://{{host}}/oauth2/clients
Method: POST
请求 Body:
{
"client_name": "测试业务系统",
"grant_types": [
"authorization_code",
"implicit",
"refresh_token"
],
"response_types": [
"token id_token",
"code",
"token"
],
"scope": "offline openid all",
"redirect_uris": [
"https://localhost/callback"
],
"post_logout_redirect_uris": [
"https://localhost/logout"
],
"metadata": {
"device": {
"name": "测试业务系统",
"client_type": "web",
"description": "web"
}
}
}
请求说明:
参数名 | 说明 |
---|---|
client_name | 业务系统名称,按需填写 |
grant_types | 授权类型,不需要修改 |
response_types | 响应类型,不需要修改 |
scope | 适用范围,不需要修改 |
redirect_uris | 重定向地址列表,无实际用处,可以使用虚构地址,但是调用后续接口时需要保持一致,需要记录 |
post_logout_redirect_uris | 登出地址列表,无实际用处,可以使用虚构地址 |
metadata | 元数据,无实际用处,name 字段和 client_name 一致即可 |
响应 body:
{
"client_id": "9d33abd5-204b-4a08-8bf2-5dc6a7f08b9f",
"client_secret": "EBxXDrytts~Z"
}
响应说明:
参数名 | 说明 |
---|---|
client_id | 客户端 id,需要记录,后续接口需要适用 |
client_secret | 客户端密钥,需要记录 |
这一步需要记录 client_id、client_secret、redirect_uris 三个字段。如果遗失,没有办法恢复
Postman 截图:
管理员应提供 Client_id 、Redirect_uri、Plugin_id 、 Plugin_secret 和 username 给业务系统。
这一步应由业务系统操作
一份完整的 JWT 数据包含三部分:
Header: 头部
Payload: 负载
Signature: 签名
对于该认证过程,Header 固定如下:
{
"alg": "HS256",
"typ": "JWT"
}
Header 请求说明:
参数名 | 说明 |
---|---|
alg | 签名算法,不需要修改 |
typ | JWT 类型,不需要修改 |
Payload 如下:
{
"username": "test10",
"exp": 1618467914
}
Payload 请求说明:
参数名 | 说明 |
---|---|
username | 需要登录的 AnyShare 用户名 |
exp | 临时密钥的过期时间戳,注意不是访问令牌的过期时间,一般设置为1到2分钟即可 |
Signature: 签名使用 AnyShare 提供的 Plugin_secret 使用 HS256 算法计算。
实际使用过程中,可以使用各类 JWT 库来生成临时密钥,Python 和 Java 的实现如下。 Python 版本:
import time
import jwt
def get_token(username, secret):
payload = {
"username": username,
"exp": int(time.time()) + 60
}
encoded = jwt.encode(payload, secret, algorithm="HS256")
return encoded
if __name__ == '__main__':
print(get_token("xxx", "xxxx"))
其中 username 为要登录的用户名,secret 为 Plugin_secret。
Java 版本:
package com.example.jwtTest;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map;
public class demo {
public String createJwt(String username, String secret, long expire) throws UnsupportedEncodingException {
Date now = new Date();
Date expireDate = new Date(now.getTime() + 1000 * expire);
Algorithm algorithm = Algorithm.HMAC256(secret);
String token = JWT.create()
.withClaim("username", username) // 增加Payload数据
.withExpiresAt(expireDate) // 过期时间
.sign(algorithm);
return token;
}
public static void main(String[] args) throws UnsupportedEncodingException {
demo Demo = new demo();
//过期时间 60 秒后
long expire = 60;
// 秘钥
String username = "用户名";
String secret = "xxx";
System.out.println(Demo.createJwt(username, secret, expire));
}
}
其中 username 为要登录的用户名,secret 为 Plugin_secret。
C# 版本:
using System;
using System.Collections.Generic;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
namespace ConsoleApp
{
class Program
{
public static string CreateJwtToken(IDictionary payload, string secret, IDictionary extraHeaders = null)
{
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var token = encoder.Encode(payload, secret);
return token;
}
static void Main(string[] args)
{
// 配置项(用户名和plugin_secret)
var username = "用户名";
var secret = "xxx";
var extraHeaders = new Dictionary { };
//过期时间(可以不设置,下面表示签名后 60 秒过期)
double exp = (DateTime.UtcNow.AddSeconds(60) - new DateTime(1970, 1, 1)).TotalSeconds;
var payload = new Dictionary{
{ "username", username },
{ "exp", exp },
};
var token = CreateJwtToken(payload, secret, extraHeaders);
Console.WriteLine(token);
Console.ReadKey();
}
}
}
其中 username 为要登录的用户名,secret 为 Plugin_secret。
这一步需要记录生成的 As_code,用于换取访问令牌
Python 版截图:
这一步应由业务系统操作
可以使用 http 请求按以下方式生成业务系统客户端:
URL: https://{{host}}/api/authentication/v1/sso
Method: POST
请求 Body:
{
"client_id": "xxx",
"redirect_uri": "xxx",
"response_type": "token id_token",
"scope": "offline openid all",
"udids": [
""
],
"credential": {
"id": "xxx",
"params": {
"as_code": "xxx"
}
}
}
请求说明:
参数名 | 说明 |
---|---|
client_id | 第一步生成的 client_id |
redirect_uri | 第一步使用的 redirect_uris 中的一个 uri |
response_type | 响应类型,不需要修改 |
scope | 适用范围,不需要修改 |
udids | 唯一标识符,可以留空 |
credential.id | 插件id,即爱数提供的 Plugin_id |
credential.params.as_code | 第二部生成的 As_code |
响应 body:
{
"access_token": "TU6Vpwz-RMw71SuhsUHNPV5B5-eruDY6CxFo3vMaucc.Jm0TWZ9cp1zvoD4CEzqefjNjCDCKXEih94MUwgO6cMs",
"expirses_in": 3599,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzpmZmY4NTM2NS00YTZmLTQ5OWMtYjljNi1hMzMxNmQ0NzJjMWQiLCJ0eXAiOiJKV1QifQ.eyJhdF9oYXNoIjoiR21IZmR2UWU3dVU4OVA3V2wya015USIsImF1ZCI6WyIxMzJlYzc4Ny0zYjI2LTQ2N2UtODMzNS1lNDExNDBlNjZjNzYiXSwiYXV0aF90aW1lIjoxNjE4NDY3OTA2LCJleHAiOjE2MTg0NzE1MDYsImlhdCI6MTYxODQ2NzkwNiwiaXNzIjoiaHR0cHM6Ly8xMjEuMzYuMTkuOTI6NDQzLyIsImp0aSI6Ijc5Mzk4NmZmLTI4MmUtNDA3NS05YjFmLWY3MjI1NGJhOWE1YSIsIm5vbmNlIjoiM2ZhNGI0MGYtYThiMC00MTg4LTg2YTAtMmVmOGRiYjkwYzk1IiwicmF0IjoxNjE4NDY3OTA2LCJzaWQiOiI4ZDY5ODg5OC02ZWZkLTQ3NTMtYWI0NS1jNGI4MTdjMDQyYTUiLCJzdWIiOiI4NzU2MmM3MC05ZDkxLTExZWItOWM4MS1mYTE2M2VmOGUzYzgifQ.rzj_0vQLkzX4OHOAZysbRwcuticqzvLcwHZJnxH6pTbV3-tmgjLM_h4K3mMrT8mqbLGeMc8M4i0mzHchQ6RRWwQbaHnS911voW6o1fYbUi6iafMtgyPcDpjCUiyaSGq0tl2kSjbmJa7kwdmIbDD48nYPjIGhmkflNlPArujiRrSCklxKsAGMIEqoREGuYflGPO3_NvqaRvKBkxo9QuJF3xullM8rf3JJN6TOeYH-tAxALtM2rlDClTHPXCJAkoM0ZjDRDCd3A6l0NYvIkzFGsAtz4wnbOEcwmPqn1Yj1vNWwP4uH0f_x9MLpGIJ1vJAtEyhMcw4OG3qryjEzyq3F-jTAwirnUrqNNznHtGBI1QKl-bavZwuanDkkZW7mYMOFxVR_ZzzReQUFlhaANmGiQVpHQUpzDJJ5rVlxSv9atTWiYaUKgCsQ88o5T4gp6zcu4MUKGvog6I5OH3aruwEB4UTH-0F16NF3_ZPFRhv2frxTt4Jx2lgXBX3dQhKWYEoMvxUwy8jJWnDyPqRKYJI6u8X8KhtvbcefbwwUTnojBEOStcw89OID1Hcqo-C5PyLxFG5FpTYo7N3524AjgXPmEadczSuh76TMQckUSalBtxuK4igOFT8C7mFm1FE6OPjViLse9gWiQUwNWA5aIIJQy0Yivaw0Lgt8ZKYl8EomEgU",
"scope": "offline openid all",
"token_type": "bearer"
}
响应说明:
参数名 | 说明 |
---|---|
access_token | 访问令牌,可以用于调用其他 OpenDoc API |
expirses_in | 访问令牌过期时间戳 |
id_token | 注销用户使用的令牌,不需要使用 |
scope | 使用范围 |
token_type | 访问令牌类型,固定为 bearer |
至此,已经获取到调用 OpenDoc API 使用的 Access_token。
Postman 截图:
关于获取 Access_token,需要注意以下事项:
/sso 接口不支持并发调用,代码调用时需要加锁
Access_token 会在一定时间后过期(一般为1小时),需要业务系统缓存使用并定时(如50分钟)刷新
Access_token 建议添加在请求头中使用,格式为 Authorization: Bearer Access_token
使用临时令牌换取 Access_token 不是 AnyShare 自带功能,需要集成开发工程师开发定制版的第三方认证插件后才能使用
请就本文对您的益处进行评级: