s3的v2认证构造-lua

前言

本篇内容实现了相关功能的硬编码的部分,还有细节未处理,验证了可行性

相关代码记录

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
95
96
97
98
99
100
101
102
ngx.log(ngx.INFO, "文件路径为:", ngx.var.uri)
ngx.log(ngx.INFO, "请求方法为:", ngx.var.request_method)
--这个打印的是收到的header的内容
ngx.log(ngx.INFO, "请求header2为:", ngx.req.raw_header(true))

--获取编码需要的信息
ngx.log(ngx.INFO, "请求的method", ngx.var.request_method)
ngx.log(ngx.INFO, "请求的content-md5:", ngx.req.get_headers()['content-md5'])
ngx.log(ngx.INFO, "请求的content-type:", ngx.req.get_headers()['content-type'])
ngx.log(ngx.INFO, "请求的date:", ngx.req.get_headers()['date'])
--从这里开始的获取的应该进行一个key的排序,动态的变量,然后拼接
ngx.log(ngx.INFO, "请求的x-amz-date:", ngx.req.get_headers()['x-amz-date'])
ngx.log(ngx.INFO, "请求的x-amz-meta-s3cmd-attrs:", ngx.req.get_headers()['x-amz-meta-s3cmd-attrs'])
ngx.log(ngx.INFO, "请求的x-amz-storage-class:", ngx.req.get_headers()['x-amz-storage-class'])

local string_to_sign = ngx.var.request_method .. "\n"
if ngx.req.get_headers()['content-md5'] == nil then
string_to_sign = string_to_sign .. "\n"
else
string_to_sign = string_to_sign .. ngx.req.get_headers()['content-md5']
end

if ngx.req.get_headers()['content-type'] == nil then
string_to_sign = string_to_sign .. "\n"
else
string_to_sign = string_to_sign .. ngx.req.get_headers()['content-type'] .. "\n"
end

if ngx.req.get_headers()['date'] == nil then
string_to_sign = string_to_sign .. "\n"
else
string_to_sign = string_to_sign .. ngx.req.get_headers()['date'] .. "\n"
end

local headers = ngx.req.get_headers()
local hkeys = {}
for k,_ in pairs(headers) do
table.insert(hkeys, k)
end
table.sort(hkeys)

for _,key in pairs(hkeys) do
if string.find(key,"x-amz-") ~= nil then
if key == "x-amz-storage-class" then
ngx.log(ngx.INFO,"需要替换的class:",key,headers[key])
string_to_sign = string_to_sign .. key .. ":" .. "STANDARD" .. "\n"
else

ngx.log(ngx.INFO,"zp_key_panduan: ", key)
string_to_sign = string_to_sign .. key .. ":" .. headers[key] .. "\n"
end
end
if string.find(key,"x-emc-") ~= nil then
string_to_sign = string_to_sign .. key .. ":" .. headers[key] .. "\n"
end
end
string_to_sign = string_to_sign .. ngx.var.uri

ngx.log(ngx.INFO,"自定义的string_to_sign:",string_to_sign)

-- print(string_to_sign)
--截取函数
function Str_Cut(str,s_begin,s_end)

local StrLen = string.len(str)
local s_begin_Len = string.len(s_begin)
local s_end_Len = string.len(s_end)
local s_begin_x = string.find(str, s_begin, 1)
--print(s_begin_x)
local s_end_x = string.find(str, s_end, s_begin_x+1)
--print(s_end_x)
local rs=(string.sub(str, s_begin_x+s_begin_Len, s_end_x-1))
return rs

end
--

local secret_key = "test1"
local digest = ngx.hmac_sha1(secret_key, string_to_sign)
ngx.log(ngx.INFO,"加密后的Authorization:",ngx.encode_base64(digest))
local header_authorization = ngx.req.get_headers()["authorization"]
--local accesskey = string.match(header_authorization,"%s+.+:")
local auth_start,auth_end,auth_name,auth_access,auth_authorization = string.find(header_authorization,'(.+)%s(.+):(.+)')
ngx.log(ngx.INFO,"accesskey:",auth_access)
ngx.log(ngx.INFO,"authorization:",auth_authorization)

--这个是从header里面提取的原始的
--new_auth= "AWS " .. auth_access ..":" .. auth_authorization
-- 下面是自己在openresty里面重新构造的
new_auth= "AWS " .. auth_access ..":" .. ngx.encode_base64(digest)
ngx.log(ngx.INFO,"new_auth:",new_auth)
--到这里完成了相关的构造,现在要尝试修改headers的内容以及重新生产的auth
ngx.req.set_header("Authorization", new_auth )
ngx.req.set_header("x-amz-storage-class", "STANDARD" )
ngx.log(ngx.INFO,"获取的header的authorization: ",ngx.req.get_headers()["authorization"])
--
local attrs = ngx.req.get_headers()["x-amz-meta-s3cmd-attrs"]
ngx.log(ngx.INFO,"获取的x-amz-meta-s3cmd-attrs",attrs)


local date=os.date("%Y%m%d%H%M%S");
ngx.log(ngx.INFO, "当前时间:",date)

在s3传输的过程中,可以通过构造改变请求的方式,在中间截取认证,并且控制数据流向