首页 > 系统相关 >Nginx鉴权功能实现

Nginx鉴权功能实现

时间:2023-04-05 20:14:18浏览次数:79  
标签:功能 .. ngx uri auth Nginx local 鉴权

背景

鉴权的功能是防止盗链,别人一直访问你的连接,把你的服务器打爆,当鉴权失败时(md5值计算错误、时间戳过期),nginx直接返回403。
鉴权主要分为四种:

  • 时间戳鉴权
  • 远程鉴权
  • Referer黑白名单
  • IP黑白名单

在使用上,一般推荐时间戳鉴权和远程鉴权,或者两者同时使用,剩下两项规避鉴权非常容易。

时间戳鉴权介绍(LSS的方式)

为确保视资源被非法获取,提供token认证和有效期限相结合的播放地址。开启时间戳鉴权后,通过”播放地址+timestamp+secret”的方式获取完整的加密播放地址。

地址如下:

https://domain.com/live/123.m3u8?timestamp=1680709499&secret=af921173a6c64469f31fbba2fa7e7110

算secret,方式为:md5(密钥+播放地址+timestamp)

  • 密钥:在播放认证开关可以获取到播放密钥,按照步骤一已获取。

  • 播放地址:/<play.your-domain.com>/{app-name}/{stream-name}

  • timestamp:用户指定播放的超时时间,格式需要转换为十进制 Unix 时间戳,推荐一个在线转换网址

  • 将(密钥+播放地址+timestamp)拼接完成后,加密为32位小写的md5码。

    假设key=111, domain = play.domain.com, app=live, stream=123, timestamp=1680709499,md5加密后的secret为:md5(111/domain.com/live/1680709499)=秘钥

中心鉴权介绍

中心鉴权是指鉴权由用户测规定,用户请求到nginx后,nginx会发送一个请求到鉴权服务器,由鉴权服务器返回的状态码来判断这个请求鉴权是否通过。

​ 中心鉴权没有规范可言,基本都是定制化。

功能实现

通过lua实现的逻辑如下:

  1. 修改nginx.conf 主配置文件,增加rewrite_by_lua_file ,指定改写脚本
http {
  access_by_lua_file lua/access/auth.lua;
}
  1. 编写处理逻辑
local cjson = require "cjson"
local ssl = require "ngx.ssl"
local http = require('resty.http')

local globalconfiguration = require "configuration"
local tool = require "tool"
local dy_conf = ngx.shared.conf

local function isintable(value,tb)
    for k,v in pairs(tb) do
        if v == value then
            return true
        end
    end
    return false    --重点:全部跑完以后,如果非true,则返回false
end

--远程鉴权使用函数,不使用
local function center_auth()
    --获取鉴权地址
    local auth_server = globalconfiguration.chinaunicom_center_auth	--从配置文件中读取远程鉴权接口
    --获取客户端IP
    local remore_addr = ngx.var.remote_addr
    -- 获取uri
    local uri = ngx.var.uri
    -- 获取域名
    local headers = ngx.req.get_headers()
    local host = headers["Host"]
    --获取对应的id
    local auth_field = "uid"
    local args = ngx.req.get_uri_args()
    local uid = args[auth_field]
    if not uid then
        ngx.log(ngx.ERR, "client not take cneter auth  field: ".. auth_field)
        ngx.exit(403)
    end


    ngx.log(ngx.INFO, "[debug]auth_serverL: " .. auth_server, "; remore_addr: "..remore_addr .. "; uri:".. uri, ";Host: " .. host)
    local httpc = http.new()
    local url = "http://" .. auth_server.. "/kuanshijie/center_auth?uid=".. uid .."&client_ip="..remore_addr.."&client_uri=" .. uri .. "&client_host=" .. host
    ngx.log(ngx.ERR, "uri: ".. url)
    httpc:set_timeout(500)
    local res, err = httpc:request_uri(url, {
        keepalive_timeout = 500 -- 毫秒
    })
    ngx.log(ngx.INFO, "center auth status : ".. res.status)
  	if not res then		--超时放行
    	  return 
    end
    if  res.status == 403 then
        ngx.log(ngx.ERR, "center auth response 403")
        ngx.exit(403)
    end
end
--请求接口

local function lss_auth(host,time_key)
    --获取参数
    local args = ngx.req.get_uri_args()
    local client_host = args["client_host"]
    --local client_uri = ngx.var.uri
    local uri = ngx.var.request_uri
    local client_uri = tool.split(uri,"?")[1]
    local timestamp = args["timestamp"]
    if timestamp == nil then
        ngx.log(ngx.ERR, "ERROR timestamp is nil")
        ngx.exit(403)
    end
    local md5 = args["secret"]
    local timestamp_key = time_key
    local now = ngx.time()
    ngx.log(ngx.ERR, "[debug]now: ".. now .."; timestamp: ".. timestamp)
    if now > tonumber(timestamp) then
        ngx.log(ngx.ERR, "ERROR req is expired! host: ", host, " uri: ", uri)
        ngx.exit(403)
    end
    local idx = string.find(client_uri, ".m3u8")
    local uri_tmp = string.sub(client_uri, 1, idx - 1)
    local str = string.format("%s/%s%s%s", timestamp_key, host, uri_tmp, timestamp)
    local val = ngx.md5(str)
    if val ~= md5 then
        ngx.log(ngx.ERR, "ERROR req md5 is error! secret: ", md5, " val: ", val, " str: ", str)
        ngx.exit(403)
    end
    ngx.log(ngx.INFO, "DEBUG timestamp auth success! val: ", val, " timestamp: ", timestamp)

end


local function process()
    local host = ssl.server_name()
    local str = dy_conf:get(host)	--从共享内存中读取域名配置
    local conf = cjson.decode(str)
    local auth = conf["conf"]["m3u8_auth_list"]	--判断域名配置项
    if auth then
        -- 判断是否存在kuanshijie_center_auth
        if isintable("center_auth",auth) then
            --center_auth()
        end
        if isintable("lss_auth", auth) then
            local time_key = conf["conf"]["cucc_anti_md5"]	--读取key
            ngx.log(ngx.ERR, "[debug] is match lss_auth")
           lss_auth(host,time_key)
        end
    end
end
process()

以上代码块有编写时间戳鉴权和中心鉴权两个功能,案例只使用了时间戳鉴权。

标签:功能,..,ngx,uri,auth,Nginx,local,鉴权
From: https://www.cnblogs.com/feng0919/p/17290737.html

相关文章

  • url rewrite功能实现
    背景:abc.com/live/stream.m3u8需要改写成abc.com/live/stream/index.m3u8通过lua实现的逻辑如下修改nginx.conf主配置文件,增加rewrite_by_lua_file,指定改写脚本http{ rewrite_by_lua_filelua/rewrite/rewrite_main.lua;}lua/rewrite/rewrite_main.lua文件编写处......
  • mysql实现nextVal功能
    mysql实现nextVal功能首先创建表:CREATETABLE`sys_sequence`(`NAME`varchar(50)NOTNULL,`CURRENT_VALUE`int(11)NOTNULLDEFAULT'0',`INCREMENT`int(11)NOTNULLDEFAULT'1',PRIMARYKEY(`NAME`))插入记录INSERTINTOSYS_SEQUEN......
  • docker-compose 通过NGINX快速搭建负载均衡的Tomcat集群
                 docker-compose通过NGINX快速搭建负载均衡的Tomcat集群从标题也可以看出,需要三个软件,docker-compose,docker-ce(docker的运行环境),Tomcat的镜像。docker-compose和docker的安装就不用说了,都可以离线安装,安装方法见博客:(docker-compose安装方......
  • NGINX的stream模块以及实操问题
    NGINX的stream模块以及实操问题前言:nginx从1.9.0开始,新增加了一个stream模块,用来实现四层协议的转发、代理或者负载均衡等。nginx作为一个优秀的web服务器软件,毫无疑问,功能是十分强大的,但学习这种软件,如果脱离了实际操作(应用场景落地),那么就是一种耍流氓的行为。(1)关于stream域的模块......
  • 46 openEuler搭建Nginx服务器-管理Nginx
    46openEuler搭建Nginx服务器-管理Nginx46.1概述通过systemctl工具,可以对nginx服务进行管理,包括启动、停止、重启服务,以及查看服务状态等。本节介绍nginx服务的管理操作。46.2前提条件为了能够使用nginx服务,请确保您的系统中已经安装nginx服务。若未安装,可参考安装进行安装......
  • 外卖APP系统开发要完善的功能,让你运筹帷幄
     开发一个外卖APP系统对于许多商家来说都是迫在眉睫的事情,可以说外卖APP系统对于商家的帮助是非常大的。不过在开发时我们要完善一些功能,下面名锐讯动为大家介绍外卖APP系统开发要完善的功能。 1.客户端。当用户进入外卖APP的时候首先浏览到的是APP的首页,这时候要求呈现商家提......
  • delphi FastReport 常用功能
    FastReport常用功能属性和方法TfrxReport.LoadFromFilefunctionLoadFromFile(constFileName:String;ExceptionIfNotFound:Boolean=False):Boolean;从给定名称的文件中加载报表。如果文件加载成功,返回True。参数FileName文件的名称。ExceptionIfNotFound如果为T......
  • Nginx容器安装vim命令
    dockerpullnginx:1.22.1dockerrun-itdnginx:1.22.1进入nginx容器apt-getupdateapt-getinstall-yvim ......
  • Web开发的那点事--业务层常用功能
      常见功能(以博客中的文章管理为示例)   1.增加   业务:写一篇文章  技术:    前端:一个页面或者对话框,等待用户输入,数据校验成功,提交代码      后端:存储到一个数据库表格中,有可能会存进多个表格。    常见问题:是否能重复增加    2.查看......
  • Web开发的那点事--数据持久层常用功能
    数据持久层--4类功能1.增加 增加一条记录-实体(有关联,没有关联) 2.修改 修改一个字段 修改多个字段 修改哪一列或哪些列:where一列多列 主键定位,多个列定位3.删除  物理删除:删除哪一列或哪些列  逻辑删除:本质是更新操作,修改isDeleted(对所有表的记录逻辑删除,几......