Skip to content

简介

本机鉴权是指在本服务器,使用客户端传递过来的参数,来判断是否是合法的推流或者播放请求,例如:推流时使用推流地址为:

rtmp://test.publish.com/app/test?sign=120705DE7E61C5B&expire=1746451971

其中sign根据域名,流名称,过期时间,秘钥拼接后经过md5生成 后台根据域名,流名称,过期时间,秘钥一样拼接计算md5值,与传递过来的sign一致,则校验通过否则不通过;

配置

为了方便配置,mms中设计了一个非常简洁,且扩展性很好,使用起来也很直观的鉴权配置(鉴权配置适用于推流也适用于播放或者回源url生成)

最简化鉴权配置

例如在推流域名test.publish.com.yaml中,配置最简单的(当然还可以生成很复杂的,后面会讲)推流鉴权如下:

yaml
type: publish
name: test.publish.com
apps:
  - name: app                   # 接入点名称
    publish_auth_check:         # 推流鉴权
      enabled: true             # 使能开关
      checks:                   # 校验项
        - "${url_params[publishKey]} == 123" # 静态鉴权(static)

该鉴权表示取url的叫publishKey的参数值,和123这个值做对比,一样则通过,否则鉴权失败。

鉴权占位符

上面为了让大家有直观的感受,介绍了下最简单的鉴权规则,可以看到url_params[publishKey]在这里是一个特殊的表示,我们称为占位符,类似printf中的%s。

占位符使用${}括起来,具体需要替换成什么内容,根据{}里面的内容来,下面我来罗列下目前mms-server里面已经实现的占位符及功能:

占位符解释举例
${domain}这个占位符将被域名替换
${app}这个占位符将被接入点替换
${stream_name}这个占位符将被流名称替换
${stream_type}这个占位符将被流类型替换,例如rtmp,webrtc,flv
${url_params[key]}这个占位符将被url中的相应参数替换,参数名称key例如请求rtmp://test.com/app/stream?key=abc,则这个占位符会被替换为abc
${header_params[key]}这个占位符将请求的header中的参数,参数名称key例如http的请求头部"key: 123",则这个占位符会被替换为123
${params[key]}这个占位符将被用户自定义计算生成的参数替换,参数名称key后续举例

参数生成方法

通过上面的鉴权占位符,获取到域名,接入点,流名称和参数,我们还需要对这些参数进行计算,例如将${domain}/${app}/${stream_name}?key=abc&expire=123,做md5计算得到一个sign值。这就需要一些先确定一些计算方法入md5,sha1,base64等, 方法在params配置里面有效,格式为: 方法名称(参数...) 下面是mms-server里面已经定义的一些方法:

名称参数个数解释
string(p1)1例如string(1234)将生成字符串1234
get_time()0例如get_time()将获取到系统当前的unix时间戳
md5_upper(p1)1例如md5_upper(${app}/${stream_name}/${url_params[key]}),假如传入key=abc,app=app,stream=stream,那么会把app/stream/abc计算出md5:7B5F8F4411943200D7CDCA6B3A45AA15
md5_lower(p1)1例如md5_lower(${app}/${stream_name}/${url_params[key]}),假如传入key=abc,app=app,stream=stream,那么会把app/stream/abc计算出md5:7b5f8f4411943200d7cdca6b3a45aa15
hmac_sha1(p1,p2)2hmac_sha1(${params[SignStr]},${params[SecretKey]}),将会使用自定义生成的参数SignStr和SecretKey进行hmac_sha1计算
base64(p1)1base64(${params[HMAC]}),将会使用自定义生成的参数HMAC,做base64计算
add(p1,p2)2add(${params[time]},10),会将自定义时间参数+10得到最终值
sub(p1,p2)2sub(${params[time]},10),会将自定义时间参数-10得到最终值
bin_to_hex(p1)2bin_to_hex(${params[HMAC]}),会将自定义参数HMAC的二进制数据转为16进制字符串

配置相关前置内容就介绍完了,下面使用具体的示例,来说明这套鉴权配置系统的灵活性:

配置示例1

配置示例如下:

yaml
type: publish
name: test.publish.com
apps:
  - name: app                   # 接入点名称
    publish_auth_check:         # 限时鉴权(expiry)
      params:
        key: string(sys@test.publish.com)
        time: get_time()
        token: md5_upper(${params[key]}/${stream_name}/${url_params[expire]})
      checks:                   # 校验项
        - "${url_params[token]} == ${params[token]}"
        - "${$url_params[expire]} < ${params[time]}"

自定义生成的参数一般使用的格式为:参数名: 参数生成方法

  • key: string(sys@test.publish.com) 表示${params[key]}这个占位符的值是sys@test.publish.com
  • time: get_time() 表示${params[time]}这个占位符的值是当前系统unix时间戳,例如:1746451971
  • token: md5_upper(params[key]/{stream}/{url_params[expire]}) 表示${params[token]}这个占位符的值是使用前面计算的key/流名称/url中的参数expire计算得到大写的md5值

checks:表示需要进行什么校验

  • "${url_params[token]} == ${params[token]}" 表示需要校验url参数中叫token的参数,必须和自定义生成的${params[token]}值一样。
  • "${url_params[expire]} < ${params[time]}" 表示需要校验url参数中叫expire的参数,必须小于自定义生成的${params[time]}参数,也就是不能过期

配置示例2

配置示例如下:

yaml
type: publish
name: test.publish.com
apps:
  - name: app                   # 接入点名称
    publish_auth_check:         # 限时鉴权sk(expiry_sk)
      params:
        SignStr: string(/${app}/${stream_name}/?e=${url_params[e]})
        SecretKey: string(312ae9gd2BrCfpTdF4U8aIg9Puh62K4eEGY72Ea_)
        AccessKey: string(7O7hf7Ld1RrC_fpZdFvU8aCgOPuhw2K4eapYOdII)
        HMAC: hmac_sha1(${params[SecretKey]},${params[SignStr]})
        HMACStr: bin_to_hex(${params[HMAC]})
        Base64: base64(${params[HMACStr]})
        Token: string(${params[AccessKey]}:${params[Base64]})
        time: get_time()
      checks:                   # 最终校验项
        - "${url_params[token]} == ${params[Token]}"
        - "${url_params[e]} < ${params[time]}"

推流url为:

yaml
rtmp://test.publish.com/app/test?e=1234&token=7O7hf7Ld1RrC_fpZdFvU8aCgOPuhw2K4eapYOdII:QzkyOUM1NjEzNEQ1RTFBQjVFOUE2MENGMjFFM0E1QjhEMTBGQ0IwQQ==

参数生成如下:

  1. params[SignStr] = /app/test/?e=1234
  2. params[SecretKey] = 312ae9gd2BrCfpTdF4U8aIg9Puh62K4eEGY72Ea_
  3. params[AccessKey] = 7O7hf7Ld1RrC_fpZdFvU8aCgOPuhw2K4eapYOdII
  4. params[HMAC] = hmac_sha1(${params[SecretKey]},${params[SignStr]}) 表示hmac_sha1(/app/test/?e=1234, 7O7hf7Ld1RrC_fpZdFvU8aCgOPuhw2K4eapYOdII)
  5. params[HMACStr] = bin_to_hex(${params[HMAC]}) 将HMAC转换为16进制字符串C929C56134D5E1AB5E9A60CF21E3A5B8D10FCB0A
  6. params[Base64] = base64(${params[HMAC]}) 表示base64(C929C56134D5E1AB5E9A60CF21E3A5B8D10FCB0A) = QzkyOUM1NjEzNEQ1RTFBQjVFOUE2MENGMjFFM0E1QjhEMTBGQ0IwQQ==
  7. params[Token] = string(${params[AccessKey]}😒{params[Base64]}) 表示:7O7hf7Ld1RrC_fpZdFvU8aCgOPuhw2K4eapYOdII:QzkyOUM1NjEzNEQ1RTFBQjVFOUE2MENGMjFFM0E1QjhEMTBGQ0IwQQ==
  8. params[time] = get_time() 表示:1746451971(取当前时间) 校验方法如下:
  9. url的参数token必须和params[token]一样,不一样则失败;
  10. url参数e(过期时间)必须小于1746451971

目前,在代码层面实现的就是一些常用的计算方法,比如md5,sha1,但代码切分比较清晰,自己增加占位符和方法非常容易。

推流鉴权与拉流鉴权

上面的示例,是使用publish_auth_check来表示推流鉴权,拉流鉴权也类似,名称为play_auth_check:

yaml
type: play
name: test.play.com
publish_domain: test.publish.com
apps:
  - name: app
    play_auth_check:
      enabled: true             # 使能
      params:
        key: string(sys@test.publish.com)
        time: get_time()
        token: md5_upper(${params[key]}/${stream_name}/${url_params[expire]})  #sys@test.publish.com/teststreamtitle/1792866744
      checks:
        - ${url_params[token]} == ${params[token]}
        - ${url_params[expire]} > ${params[time]}

Released under the MIT License.