文档首页 > > 开发指南>

App ID鉴权介绍

App ID鉴权介绍

分享
更新时间:2021/01/12 GMT+08:00

为了降低第三方应用集成华为云会议难度,并且提升开放接口的安全性,华为云会议开放能力中支持基于App ID的鉴权方式。App ID是一个应用的标识,同一个App ID可以同时在第三方的桌面终端、移动终端、Web应用上使用。

App ID鉴权原理

图1 第三方客户端App ID鉴权流程

鉴权前提:

  1. 开发者在华为云会议控制台上为自己的应用申请AppID,并获取App ID和App Key。
  2. 开发者在自己的服务端集成Signature生成算法,请参考“第三方服务集成Signature生成算法”。
  3. SDK初始化时传入App ID,请参考《客户端SDK参考》中的“初始化”部分。

鉴权过程:

  1. 第三方客户端将User ID(第三方User ID)发送给第三方服务器。
  2. 第三方服务器根据App ID、User ID、App Key等,生成鉴权用的签名材料Signature。
  3. 第三方服务端返回Signature,以及ExpireTime和Nonce值。
  4. 第三方客户端调用客户端SDK的Login接口,参数为User ID、Signature、ExpireTime和Nonce。
  5. 客户端SDK去华为云会议服务端鉴权。
  6. 鉴权通过后SDK获取接入Token。该Token对第三方客户端不可见,由SDK负责维护和刷新。

图2 第三方服务端App ID鉴权流程

鉴权前提:

  1. 开发者在华为云会议控制台上为自己的应用申请AppID,并获取App ID和App Key。
  2. 开发者在自己的服务端集成Signature生成算法,请参考“第三方服务集成Signature生成算法”。

鉴权过程:

  1. 第三方服务端根据调用的业务接口所需的User ID(第三方User ID),加上App ID、App Key、ExpireTime和Nonce,生成鉴权用的签名材料Signature。
  2. 第三方服务端调用华为云会议服务端的AppID鉴权接口(REST接口)。
  3. 华为云会议服务端鉴权通过后,返回接入Token。
  4. 第三方服务端使用接入Token调用其他业务接口。

1. 接口Token有效期是12~24小时。

2. 生成Signature和调用appAuth接口时可以不带User ID,如果不带User ID默认是创建企业时的创建者(企业Owner)。

3. User ID需要第三方应用保证在同一个企业内是唯一的。如果第三方开发者是SP,同一个应用在多个企业使用,接口中除了带User ID外,还需要带Corp ID(企业ID)。

4. 如果需要使用华为云会议通讯录的情况下,在登录鉴权过程中还可以携带邮箱、姓名、电话号码等信息,这些信息将被写入华为云会议的通讯录中。

App ID的申请

  1. 使用华为云账号,登录华为云会议控制台。前提是该华为云账号已经购买了华为云会议服务或者已经绑定了华为云会议企业管理员帐号,请参考“开发流程”章节中的“开发前准备”。
  2. 点击“应用管理”,再点击“创建应用”。在弹出的创建应用的输入框中输入第三方应用的名称及描述。

    图3 创建应用

  3. 记录App ID和App Key

    图4 获取App ID和App Key

  1. App Key是生成鉴权签名材料Signature的密钥,需要在第三方服务端妥善保存,不要泄露出去,否则会出现被盗用会议资源的风险。
  2. App Key只能保存在第三方服务端,不能保存在第三方终端中,否则很容易被反编译获取。
  3. App Key需要妥善保存,遗失后只能重置,不能找回。

第三方服务集成Signature生成算法

App只在单个企业内使用的情况下,生成鉴权签名材料Signature的算法如下:

Signature = HexEncode(HMAC-SHA256((App ID + ":" + User ID + ":" + ExpireTime + ":" + Nonce), appKey))

App是SP开发,需要在多个企业内使用的情况下,生成鉴权签名材料Signature的算法如下:

Signature = HexEncode(HMAC-SHA256((App ID + ":" + CorpID  + ":" + User ID + ":" + ExpireTime + ":" + Nonce), appKey))

算法说明:

  1. HMAC-SHA256的输入数据是App ID、User ID、ExpireTime、Nonce、CorpID(可选)值,中间用“:”分隔。如d5e1785afbe44c2588b642446652489e:alice@ent01:1604020600:EycLQsHwxhzK9OW8UEKWNfH2I3CGR2nINuU1EBpQ
  2. HMAC-SHA256的密钥是App Key。如tZAeEXWggfxMq32T
  3. HMAC-SHA256生成的二进制数需要转换为十六进制字符串(HexEncode),上述的数据和密钥最终生成的Signature如下:2a8c780cee3dbfe210384c3f95380732d55dfc81cfa49c5a6c44f3c1b3c2455d
  4. ExpireTime:鉴权签名材料Signature的过期时间戳。单位是秒。比如当前的系统的时间戳是1604020000,Signature有效期设置成10分钟,则ExpireTime = 1604020000+10*60 = 1604020600
  5. Nonce:随机字符串,每次计算鉴权签名材料Signature时都必须不同。字符串长度为32~64字节

1. 由于鉴权签名材料Signature是有有效期的,所以第三方服务端的系统时间和华为云会议服务端的系统时间误差不能太大(小于ExpireTime中的有效期,如上例中的10分钟)。华为云会议服务端时间已经跟标准NTP时间同步。

2. ExpireTime为0,表示永远不过期。为了防止重放攻击,不建议将ExpireTime设置为0。

Java版本的Signature生成算法源代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class HmacSHA256 {

     //十六进制字符集
     private final static char[] DIGEST_ARRAYS = {
         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
     };
     
      /**
      * 功能:Signature生成算法
      * 输入参数:
      *          1.data: HMAC-SHA256的输入数据
      *          2.key: App Key
      * 输出参数:十六进制字符串编码的HMAC-SHA256值
      */
     public static String encode(String data, String key) {
         byte[] hashByte;
         try {
             Mac sha256HMAC = Mac.getInstance("HmacSHA256");
             SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
             sha256HMAC.init(secretKey);

             hashByte = sha256HMAC.doFinal(data.getBytes("UTF-8"));
         } catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException e) {
             return null;
         }

         return bytesToHex(hashByte);
     }

     /**
      * 功能:byte类型数组转换成十六进制字符串
      * 输入参数:
      *          1.bytes:被转换的字节数组
      * 输出参数:十六进制字符串
      */
     private static String bytesToHex(byte[] bytes) {
         StringBuffer hexStr = new StringBuffer();
         for (int i = 0; i < bytes.length; i++) {
             hexStr.append(DIGEST_ARRAYS[bytes[i] >>> 4 & 0X0F]);
             hexStr.append(DIGEST_ARRAYS[bytes[i] & 0X0F]);
         }

         return hexStr.toString();
     }
 }

Python版本的Signature生成算法源代码
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import hmac
from hashlib import sha256
 
class HmacSHA256:
      def __init__(self, sig_data, sig_key):
         self.data = sig_data
         self.key = sig_key

      def encode(self):
         try:
             sig_data = self.data.encode('utf-8')
             secret_key = self.key.encode('utf-8')
             signature = hmac.new(secret_key, sig_data, digestmod=sha256).hexdigest()
         except Exception as e:
             print (e)
             raise e
          return signature

C++版本的Signature生成算法源代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <openssl/hmac.h>  
#include <string.h>  
#include <iostream>  
using namespace std;
 
const int HMAC_ENCODE_SUCCESS = 0;
const int HMAC_ENCODE_FAIL = -1;
const int HMAC_SHA256_STR_LEN = 65;
 
/**
* 功能: 字节流转换成十六进制字符串
* 输入参数:
*          1.input: 字节流指针
*          2.len: 字节流字节数
* 输出参数:
*          3.output: 输出缓冲区
*          6.output_length: Signature字符串长度
* 返回值:
*          0:失败
*          大于0的整数:转换后的字符串长度
*/
int Byte2HexStr(char * output, unsigned char * input, unsigned int len)
{
    if ((NULL == output) or (NULL == input))
    {
        return 0;
    }
 
    unsigned int i = 0;
    for (i = 0; i < len; i++)
    {
        sprintf_s(output + 2*i, HMAC_SHA256_STR_LEN-2*i, "%x%x", (input[i] >> 4) & 0x0F, input[i]&0x0F);
    }
 
    *(output + 2*i) = '\0';
 
    return 2*i;
}
 
 
/**
* 功能: Signature生成算法
* 输入参数:
*          1.key: App Key
*          2.key_length: App Key的字符串长度
*          3.input: HMAC-SHA256的输入数据
*          4.input_length: HMAC-SHA256的输入数据的字符串长度
* 输出参数:
*          5.output: Signature输出缓冲区
*          6.output_length: Signature字符串长度
* 返回值:
*          0:成功
*          -1:失败
*/
int HmacEncode(const char * key, unsigned int key_length,
    const char * input, unsigned int input_length,
    char output[HMAC_SHA256_STR_LEN], unsigned int &output_length) {
 
    //计算HMAC_SHA256的字节流
    const EVP_MD * engine = EVP_sha256();
 
    unsigned char * byte_output = (unsigned char*)malloc(EVP_MAX_MD_SIZE);
    if (NULL == byte_output)
    {
        output_length = 0;
        return HMAC_ENCODE_FAIL;
    }
    unsigned int  byte_output_length = 0;
 
    HMAC_CTX *ctx;
    ctx = HMAC_CTX_new();
 
    HMAC_Init(ctx, key, strlen(key), engine);
    HMAC_Update(ctx, (unsigned char*)input, strlen(input));
    HMAC_Final(ctx, byte_output, &byte_output_length);
 
    HMAC_CTX_free(ctx);
 
    //HMAC_SHA256的字节流转换成十六进制字符串
    int ret = Byte2HexStr(output, byte_output, byte_output_length);
    free(byte_output);
 
    if (0 == ret)
    {   
        output_length = 0;
        return HMAC_ENCODE_FAIL;
    }
    else
    {
        output_length = ret;
        return HMAC_ENCODE_SUCCESS;
    }
 
}

C++的Signature生成算法基于openssl 1.1.0以上版本实现。openssl库需要开发者自己编译和安装,请参考openssl官网

第三方客户端App ID鉴权

第三方客户端初始化SDK时,需要传入事先申请好的App ID。

  • Android SDK的初始化接口,请参考《客户端SDK参考》中“Android SDK”的“初始化”章节。
  • iOS SDK的初始化接口,请参考《客户端SDK参考》中“iOS SDK”的“初始化”章节。
  • Windows SDK的初始化接口,请参考《客户端SDK参考》中“Windows SDK”的“初始化”章节。
  • Mac SDK的初始化接口,请参考《客户端SDK参考》中“Mac SDK”的“初始化”章节。

第三方客户端登录时,从第三方服务端获取Signature、ExpireTime和Nonce后,调用终端SDK的Login接口完成鉴权。

  • Android SDK的Login接口,请参考《客户端SDK参考》中“Android SDK”的“登录”章节。
  • iOS SDK的Login接口,请参考《客户端SDK参考》中“iOS SDK”的“登录”章节。
  • Windows SDK的Login接口,请参考《客户端SDK参考》中“Windows SDK”的“登录”章节。
  • Mac SDK的Login接口,请参考《客户端SDK参考》中“Mac SDK”的“登录”章节。

第三方服务端App ID鉴权

第三方服务端通过AppID鉴权接口,完成App ID鉴权,并获取接入Token。请参考《服务端API参考》中的“执行App ID鉴权”章节。

分享:

    相关文档

    相关产品

文档是否有解决您的问题?

提交成功!非常感谢您的反馈,我们会继续努力做到更好!
反馈提交失败,请稍后再试!

*必选

请至少选择或填写一项反馈信息

字符长度不能超过200

提交反馈 取消

如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨

智能客服提问云社区提问
{{site}}{{lan}}
{{site}}{{language}}