すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo Live:URL署名のサンプルコード

最終更新日:Sep 09, 2024

このトピックでは、カスタム署名付きURLの作成方法と使用方法、およびURL署名設定の更新方法に関するサンプルコードを提供します。

署名付き URL の生成

カスタムの署名付きURLを作成する

実際のビジネスシナリオでは、取り込みURLとストリーミングURLを動的に生成する必要があります。 この場合、URL署名設定を取得し、連結ルールを使用してURLを構築できます。 このセクションでは、server SDK for Javaを例として、取り込みURLとストリーミングURLを動的に構築する方法について説明します。

説明

署名付きURLの構造については、「署名付きURLの作成」をご参照ください。

署名付きURLは認証キー有効期間に基づいて暗号化する必要があるため、取り込みURLとストリーミングURLを動的に構築する前に、URL署名設定を取得する必要があります。

URL署名設定を取得するには、DescribeLiveDomainConfigsを呼び出してドメイン名の設定を照会します。 サンプルコード:

// Replace the content in <> with actual values.
DefaultProfile profile = DefaultProfile.getProfile("<regionId>", "<ALIBABA_CLOUD_ACCESS_KEY_ID>", "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>");
IAcsClient client = new DefaultAcsClient(profile);
DescribeLiveDomainConfigsRequest describeLiveDomainConfigsRequest=new DescribeLiveDomainConfigsRequest();
describeLiveDomainConfigsRequest.setDomainName("<DomainName>");
describeLiveDomainConfigsRequest.setFunctionNames("aliauth");

DescribeLiveDomainConfigsResponse describeLiveStreamSnapshotInfoResponse = null;
try {
     describeLiveStreamSnapshotInfoResponse = client.getAcsResponse(describeLiveDomainConfigsRequest);
 } catch (ClientException e) {
     e.printStackTrace();
}
The authentication key.
String key="";
// The valid period. Unit: seconds.
long expSeconds=0l;

for(DescribeLiveDomainConfigsResponse.DomainConfig.FunctionArg f:describeLiveStreamSnapshotInfoResponse.getDomainConfigs().get(0).getFunctionArgs()){
     if("auth_key1".equals(f.getArgName())){
            key=f.getArgValue();
       }
     if("ali_auth_delta".equals(f.getArgName())){
            expSeconds=Long.valueOf(f.getArgValue());
     }
 }

 System.out.println(key);
 System.out.println(expSeconds);

認証キー有効期間を取得したら、URLを作成して暗号化できます。 関連するサンプルコードについては、このトピックの「暗号化に署名付きURLを使用する」の「Javaのサンプルコード」を参照してください。

説明
  • 取り込みURLを生成するときは、取り込みドメインの認証キー有効期間を使用する必要があります。

  • ストリーミングURLを生成するときは、ストリーミングドメインの認証キー有効期間を使用する必要があります。

URL署名設定の更新

実際のビジネスシナリオでは、定期的に認証キーを更新する必要がある場合があります。これも推奨する方法です。 この場合、BatchSetLiveDomainConfigsを呼び出して、ドメイン名のURL署名設定を更新できます。

このセクションでは、Java用のサーバーSDKを例として、URL署名設定を更新する方法について説明します。 サンプルコード:

// Replace the content in <> with actual values.
DefaultProfile profile = DefaultProfile.getProfile("<regionId>", "<ALIBABA_CLOUD_ACCESS_KEY_ID>", "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>");
IAcsClient client = new DefaultAcsClient(profile);
BatchSetLiveDomainConfigsRequest batchSetLiveDomainConfigsRequest =new BatchSetLiveDomainConfigsRequest();
batchSetLiveDomainConfigsRequest.setDomainNames("<DomainName>");
batchSetLiveDomainConfigsRequest.setFunctions("[{\"functionArgs\":[" +
        "{\"argName\":\"auth_type\",\"argValue\":\"type_a\"}," +
        "{\"argName\":\"auth_key1\",\"argValue\":\"<KEY_MAIN****>\"}," +
        "{\"argName\":\"auth_key2\",\"argValue\":\"<KEY_BAK****>\"}," +
        "{\"argName\":\"ali_auth_delta\",\"argValue\":<3600>}]," +
        "\"functionName\":\"aliauth\"}]");
try {
    BatchSetLiveDomainConfigsResponse response = client.getAcsResponse(batchSetLiveDomainConfigsRequest);
    System.out.println(new Gson().toJson(response));
    //todo something
} catch (ServerException e) {
    e.printStackTrace();
} catch (ClientException e) {
    e.printStackTrace();
}
説明
  • 上記のサンプルコードは、ドメイン名 <DomainName> のURL署名設定を更新します。 認証タイプはtype_aで、URL署名が有効になっていることを示します。 プライマリキーを示すauth_key1の値は、KEY_MAIN **** です。 セカンダリキーを示すauth_key2の値は、KEY_BAK **** です。 署名付きURLの有効期間を示すali_auth_deltaの値は3600です。

  • プライマリキーセカンダリキーの機能は同じです。 二次キーは、円滑なキー置換に使用される。 主キーを変更すると、元の主キーを使用するすべての生成されたストリーミングURLがすぐに無効になります。 プライマリキーからセカンダリキーに切り替えた場合、元のプライマリキーを使用する生成されたストリーミングURLは有効なままです。 セカンダリキーはプライマリキーとして機能します。

暗号化に署名付きURLを使用

サンプルコードin Java

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AuthDemo {
    private static String md5Sum(String src) {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        md5.update(StandardCharsets.UTF_8.encode(src));
        return String.format("%032x", new BigInteger(1, md5.digest()));
    }

private static String aAuth(String uri, String key, long exp) {
    String pattern = "^(rtmp://)?([^/?]+)(/[^?]*)?(\\\\?.*)?$";
    Pattern r = Pattern.compile(pattern);
    Matcher m = r.matcher(uri);
    String scheme = "", host = "", path = "", args = "";
    if (m.find()) {
        scheme = m.group(1) == null ?  "rtmp://" : m.group(1);
        host = m.group(2) == null ?  "" : m.group(2);
        path = m.group(3) == null ?  "/" : m.group(3);
        args = m.group(4) == null ?  "" : m.group(4);
    } else {
        System.out.println("NO MATCH");
    }

    String rand = "0";  // "0" by default, other value is ok
    String uid = "0";   // "0" by default, other value is ok
    String sString = String.format("%s-%s-%s-%s-%s", path, exp, rand, uid, key);
    String hashValue = md5Sum(sString);
    String authKey = String.format("%s-%s-%s-%s", exp, rand, uid, hashValue);
    if (args.isEmpty()) {
        return String.format("%s%s%s%s?auth_key=%s", scheme, host, path, args, authKey);
    } else {
        return String.format("%s%s%s%s&auth_key=%s", scheme, host, path, args, authKey);
    }
}

public static void main(String[] args) {
    String uri = "rtmp://example.aliyundoc.com/live/test****";  // original uri
    String key = "<input private key>";                       // private key of authorization
    long exp = System.currentTimeMillis() / 1000 + 1 * 3600;  // expiration time: 1 hour after current time
    String authUri = aAuth(uri, key, exp);                    
    System.out.printf("URL : %s\nAuth: %s", uri, authUri);
}
}

Pythonのサンプルコード

import re
import time
import hashlib
import datetime
def md5sum(src):
    m = hashlib.md5()
    m.update(src)
    return m.hexdigest()
def a_auth(uri, key, exp):
    p = re.compile("^(rtmp://)?([^/?]+)(/[^?]*)?(\\?.*)?$")
    if not p:
        return None
    m = p.match(uri)
    scheme, host, path, args = m.groups()
    if not scheme: scheme = "rtmp://"
    if not path: path = "/"
    if not args: args = ""
    rand = "0"      # "0" by default, other value is ok
    uid = "0"       # "0" by default, other value is ok
    sstring = "%s-%s-%s-%s-%s" %(path, exp, rand, uid, key)
    hashvalue = md5sum(sstring.encode('utf-8'))
    auth_key = "%s-%s-%s-%s" %(exp, rand, uid, hashvalue)
    if args:
        return "%s%s%s%s&auth_key=%s" %(scheme, host, path, args, auth_key)
    else:
        return "%s%s%s%s?auth_key=%s" %(scheme, host, path, args, auth_key)
def main():
    uri = "rtmp://example.aliyundoc.com/test/test?vhost=demo.aliyundoc.liucom"            # original uri
    key = "<input private key>"                         # private key of     authorization
    exp = int(time.time()) + 1 * 3600                   # expiration     time: 1 hour after current itme
    authuri = a_auth(uri, key, exp)                     
    print("URL : %s\nAUTH: %s" %(uri, authuri))
if __name__ == "__main__":
    main()

Goのサンプルコード

package main
import (
    "crypto/md5"
    "encoding/hex"
    "fmt"
    "regexp"
    "time"
)

func md5sum(src string) string {
    h := md5.New()
    h.Write([]byte(src))
    return hex.EncodeToString(h.Sum(nil))
}

func a_auth(uri, key string, exp int64) string {
    p, err := regexp.Compile("^(rtmp://)?([^/?]+)(/[^?]*)?(\\?.*)?$")
    if err != nil {
        fmt.Println(err)
        return ""
    }
    m := p.FindStringSubmatch(uri)
    var scheme, host, path, args string
    if len(m) == 5 {
        scheme, host, path, args = m[1], m[2], m[3], m[4]
    } else {
        scheme, host, path, args = "rtmp://", "", "/", ""
    }
    rand := "0" // "0" by default, other value is ok
    uid := "0"  // "0" by default, other value is ok
    sstring := fmt.Sprintf("%s-%d-%s-%s-%s", path, exp, rand, uid, key)
    hashvalue := md5sum(sstring)
    auth_key := fmt.Sprintf("%d-%s-%s-%s", exp, rand, uid, hashvalue)
    if len(args) != 0 {
        return fmt.Sprintf("%s%s%s%s&auth_key=%s", scheme, host, path, args, auth_key)
    } else {
        return fmt.Sprintf("%s%s%s%s?auth_key=%s", scheme, host, path, args, auth_key)
    }
}

func main() {
    uri := "rtmp://example.aliyundoc.com/live/test****" // original uri
    key := "<input private key>"                                           // private key of authorization
    exp := time.Now().Unix() + 3600                                        // expiration time: 1 hour after current itme
    authuri := a_auth(uri, key, exp)                                       
    fmt.Printf("URL : %s\nAUTH: %s", uri, authuri)
}

PHPのサンプルコード

<?php
function a_auth($uri, $key, $exp) {
    preg_match("/^(rtmp:\/\/)?([^\/?]+)?(\/[^?]*)?(\\?.*)?$/", $uri, $matches);
    $scheme = $matches[1];
    $host = $matches[2];
    $path = $matches[3];
    $args = $matches[4];
    if  (empty($args)) {
        $args ="";
    }
    if  (empty($scheme)) {
        $scheme ="rtmp://";
    }
    if  (empty($path)) {
        $path ="/";
    }
    $rand = "0";
    // "0" by default, other value is ok
    $uid = "0";
    // "0" by default, other value is ok
    $sstring = sprintf("%s-%u-%s-%s-%s", $path, $exp, $rand, $uid, $key);
    $hashvalue = md5($sstring);
    $auth_key = sprintf("%u-%s-%s-%s", $exp, $rand, $uid, $hashvalue);
    if ($args) {
        return sprintf("%s%s%s%s&auth_key=%s", $scheme, $host, $path, $args, $auth_key);
    } else {
        return sprintf("%s%s%s%s?auth_key=%s", $scheme, $host, $path, $args, $auth_key);
    }
}
$uri = "rtmp://example.aliyundoc.com/live/test****";
$key = "<input private key>";
$exp = time() + 3600;
$authuri = a_auth($uri, $key, $exp);
echo "URL :" . $uri;
echo PHP_EOL;
echo "AUTH:" . $authuri;
?>

C# のサンプルコード

using System;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Text;
public class Test
{
    public static void Main()
    {
        string uri= "rtmp://example.aliyundoc.com/live/test****";  // original uri
        string key= "<input private key>";                           // private key of authorization
           DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
         string exp  = Convert.ToInt64((DateTime.Now - dateStart).TotalSeconds+3600).ToString(); // expiration time: 1 hour after current time
        string authUri = aAuth(uri, key, exp);
        Console.WriteLine (String.Format("URL :{0}",uri));
        Console.WriteLine (String.Format("AUTH :{0}",authUri));
    }
    public static string aAuth(string uri, string key, string exp)
    {
        Regex regex = new Regex("^(rtmp://)?([^/?]+)(/[^?]*)?(\\\\?.*)?$");
        Match m = regex.Match(uri);
        string scheme = "rtmp://", host = "", path = "/", args = "";
        if (m.Success)
        {
            scheme=m.Groups[1].Value;
            host=m.Groups[2].Value;
            path=m.Groups[3].Value;
            args=m.Groups[4].Value;
        }else{
            Console.WriteLine ("NO MATCH");
        }
        string rand = "0";  // "0" by default, other value is ok
        string uid = "0";   // "0" by default, other value is ok
        string u = String.Format("{0}-{1}-{2}-{3}-{4}",  path, exp, rand, uid, key);
        string hashValue  = Md5(u);
        string authKey = String.Format("{0}-{1}-{2}-{3}", exp, rand, uid, hashValue);
        if (args=="")
        {
            return String.Format("{0}{1}{2}{3}?auth_key={4}", scheme, host, path, args, authKey);
        } else
        {
            return String.Format("{0}{1}{2}{3}&auth_key={4}", scheme, host, path, args, authKey);
        }
    }
    public static string Md5(string value)
    {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        byte[] bytes = Encoding.ASCII.GetBytes(value);
        byte[] encoded = md5.ComputeHash(bytes);
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<encoded.Length; ++i)
        {
            sb.Append(encoded[i].ToString("x2"));
        }
        return sb.ToString();
   }
}

関連ドキュメント

アクセス制御の詳細については、開発者ガイドのアクセス制御のトピックを参照してください。

Java用サーバーSDKの使用方法の詳細については、「Java用サーバーSDKの使用」をご参照ください。