【CDN】URL鉴权说明
lasttime 2022-08-27 13:12:42

·为什么要配置URL鉴权?

CDN分发的内容默认为公开资源,用户拿到URL后均可访问,为防止站点资源被恶意下载盗用,除了通过Referer防盗链、IP黑白名单等防控方式,您还可以采用URL鉴权,自行配置校验鉴权URL中的加密串和时间戳,更安全有效地保护源站资源。本文主要介绍鉴权URL的逻辑、开启或关闭鉴权、以及验证方法。

 

·CDNCloud的鉴权方式

    CDNCloud的鉴权主要有两式:一、鉴权JWT模式;二、鉴权ALI-A模式。

 

·鉴权的配置说明

一、鉴权JWT方式

·  a.鉴权JWT方式加密URL构成

   http://DomainName/Filename?auth_key=<jwt字符串>

·  b.鉴权字段说明

字段

描述

DomainName

CDN站点的域名。

Filename

实际回源访问的URL,鉴权时Filename需以正斜线(/)开头。

auth_key

您设定的鉴权密钥。

jwt字符串

基于jwt开放标准计算出来的

 

·  c.JWT构成

  JWT就是一段字符串,由三段信息构成的,将这三段信息文本用  .链接一起就构成了Jwt字符串。就像这样

        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

  第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).

  1、头部(header)

    jwt的头部承载两部分信息:

      声明类型,这里是jwt

      声明加密的算法 通常直接使用 HMAC SHA256

    完整的头部就像下面这样的JSON

        {

          'typ': 'JWT',

          'alg': 'HS256'

        }

    然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分.

        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

  2、载荷(payload)用来存放实际需要传递的数据。

    2.1、载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分

      标准中注册的声明

      公共的声明

      私有的声明

    2.2、标准中注册的声明 (建议但不强制使用

      sub: jwt所面向的用户

      name: 接收jwt的一方

      iat: jwt的签发时间

    2.3、公共的声明 

      公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

    2.4、私有的声明 

       私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息

        定义一个payload:

        {

          "sub": "1234567890",

          "name": "John Doe",

          "iat": 1516239022

        }

    然后将其进行base64加密,得到JWT的第二部分

        eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

  3、签证(signature)

    JWT的第三部分是一个签证信息,这个签证信息由三部分组成:

      header (base64后的)

      payload (base64后的)

      secret

    这个部分需要base64加密后的headerbase64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

        // javascriptvar encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);var signature = HMACSHA256(encodedString, 'secret'); // 7m6JhjDj0Blnye6rLAat5mX0BCivb9XXuEY15LprW8c

    将这三部分用.连接成一个完整的字符串,构成了最终的jwt:

        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.7m6JhjDj0Blnye6rLAat5mX0BCivb9XXuEY15LprW8c

  注意:secret是指用户设置的密钥,保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

  关于签发和核验JWT,我们可以使用Django REST framework JWT扩展来完成。

  4、根据上述构成加密URL 

        http://DomainName/Filename?auth_key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.7m6JhjDj0Blnye6rLAat5mX0BCivb9XXuEY15LprW8c

        鉴权Key的快速计算请参考   https://jwt.io/#debugger-io

·  d.鉴权Key的写法示例

        {

    "keys": [{

            "k": "<Base64签名密钥>",

            "kty": "<密钥生成时使用的加密算法,默认:oct>"

             }]

}

二、鉴权ALI-A方式

·   a.鉴权ALI-A方式加密URL构成

    http://DomainName/Filename?auth_key=timestamp-rand-uid-md5hash

        鉴权字段说明

字段

描述

DomainName

CDN站点的域名。

Filename

实际回源访问的URL,鉴权时Filename需以正斜线(/)开头。

auth_key

您设定的鉴权密钥。

timestamp

签算服务器生成鉴权URL的时间,与鉴权URL有效时长共同控制鉴权URL的失效时间。时间点取自签算服务器的Unix时间戳(Unix时间戳是从UTC时间19700101000000秒到现在的总秒数,是十进制的整型正数,固定长度为10,与时区无关),以十六进制形式表示

说明 多数情况下,鉴权URL的有效时长为CDN配置的鉴权URL有效时长。有时在签算增加鉴权URL的有效时长的,此时,timestamp=签算服务器上的Unix时间戳+签算服务器上加的有效时长;鉴权URL实际有效时长=timestamp+CDN配置的鉴权URL有效时长。

rand

随机数。建议使用UUID,不能包含中划线(-),例如:477b3bbc253f467b8def6711128c7bec

uid

用户ID,暂未使用,设置成0即可。

md5hash

通过MD5算法计算出的字符串,由数字0~9和小写英文字母a~z混合组成,固定长度为32

md5hash的值通过以下字符串计算得到。

sstring = "URI-Timestamp-rand-uid-PrivateKey"URI是用户的请求对象相对地址,不包含参数,如/Filenamemd5hash = md5sum(sstring)

·  b.鉴权逻辑说明

    CDN服务器接到资源访问请求后,判断最终生成鉴权URL请求中的timestamp+鉴权URL有效时长是否小于当前时间。

    o    结果一致,鉴权通过,返回资源请求。

    说明 当鉴权通过时,会去掉URL中与鉴权相关的那部分参数,可以提高缓存命中率,减少回源流量:

    o    结果不一致,鉴权失败,返回HTTP 403错误。

    o    实际生成缓存keyURL格式:http://DomainName/FileName

    o    实际回源的URL格式:http://DomainName/FileName

    o    如果timestamp+鉴权URL有效时长小于当前时间,服务器判定过期失效,并返回HTTP 403错误。

    o    如果timestamp+鉴权URL有效时长大于当前时间,则以sstring方式构造出一个字符串(参考表格中sstring构造方式),然后使用MD5算法算出md5hash的值,再将计算出的md5hash值与用户访问请求中携带的md5hash的值进行比对。

·  c.鉴权URL示例

    通过以下示例说明,您可以准确理解鉴权ALI-A方式的实现方式。

示例条件

    o    回源请求对象:

    http://cdn.example.com/video/standard/test.mp4

    说明 如果您的回源请求对象中有中文汉字,请先对其进行URL转码(即Encode),再进行鉴权URL的拼接。

    o    设置密钥为:cdncloud1234

    o    签算服务器生成鉴权URL的时间:2022-08-22 10:00:00UTC+8),转换为十进制的整形数值为1661133600

·  d.拼接流程

  1.    CDN服务器构造出一个用于计算md5hash的签名字符串。

    /video/standard/test.mp4-1661133600-0-0-cdncloud1234

  2.    根据该签名字符串,CDN服务器会计算出md5hash

    md5hash = md5sum("/video/standard/test.mp4-1661133600-0-0-cdncloud1234") = 19f27227db0c4304701915f48129a592

  3.    生成鉴权URL

    http://cdn.example.com/video/standard/test.mp4?auth_key=1661133600-0-0-19f27227db0c4304701915f48129a592

  当使用客户端提供的加密URL进行访问时,如果CDN服务器计算出来的md5hash值与访问请求中带的md5hash值相同,都为19f27227db0c4304701915f48129a592,则鉴权通过,反之鉴权失败。

·  e.鉴权Key的写法示例

        {

          "secret": "cdncloud1234",

          " ttl": "1800"

        }


相关文档
上一篇:裸金属服务器(即将上线)
下一篇:【CDN】鉴权ALI-A模式的Key的算法示例
猜你想看