AnyBackup
性能爆表
AnyShare
如何购买
我已是Anyshare 客户
AnyRobot
如何购买
购买 AnyRobot 订阅服务
我已是 AnyRobot 客户
一对一在线咨询
我是 AnyRobot 新客户
一对一在线咨询
AnyDATA

爱数博客

全部 AnyBackup AnyShare AnyRobot AnyDATA AnyFabric

AnyShare 7 使用 sso 方法获取业务系统访问令牌

2022-09-26 2448 0

背景

业务系统和 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 的过程,对于有能力的服务商,可以自行开发插件

Access_token 获取步骤

一、获取 Plugin_id 和 Plugin_secret

这一步应由管理员操作

登录 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 生成临时密钥

这一步应由业务系统操作

一份完整的 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 自带功能,需要集成开发工程师开发定制版的第三方认证插件后才能使用

请就本文对您的益处进行评级:

相关文章

热门标签

版本发布 在线教学

拨打400

免费销售咨询热线

400 8216055

7*24 小时免费售后服务热线

400 880 1569

购买咨询

购买咨询

售后服务

售后服务

返回顶部

为了给您提供更优质的服务,请您先完善以下信息:
确认提交

扫码关注

爱数技术支持中心公众号