如何解决尝试使用 AWS SES API 发送电子邮件时出现“NotAuthorizedException/”
我尝试通过发出 HTTPS 请求在 lua 中使用 AWS SES API 发送电子邮件,但我在响应对象正文中收到“NotAuthorizedException/”。有人可以帮助我了解为什么会出现此错误以及可能的解决方案。
用于调用 API,
local aws_v4 = require ("kong.plugins.kong-rate-limit.ses.v4")
local http = require "resty.http"
local cjson = require "cjson.safe"
local Meta = require "kong.Meta"
local constants = require "kong.constants"
local resty_http = require 'resty.http'
local tostring = tostring
local tonumber = tonumber
local type = type
local fmt = string.format
local ngx_encode_base64 = ngx.encode_base64
local ngx_time = ngx.time
local string_match = string.match
local os_time = os.time
local concat = table.concat
local AWS_PORT = 443
local function iso8601_to_epoch(date_iso8601)
local inYear,inMonth,inDay,inHour,inMinute,inSecond,inZone = string_match(date_iso8601,'^(%d%d%d%d)-(%d%d)-(%d%d)T(%d%d):(%d%d):(%d%d)(.-)$')
local zHours,zMinutes = string_match(inZone,'^(.-):(%d%d)$')
local returnTime = os_time({year=inYear,month=inMonth,day=inDay,hour=inHour,min=inMinute,sec=inSecond,isdst=false})
if zHours then
returnTime = returnTime - ((tonumber(zHours)*3600) + (tonumber(zMinutes)*60))
end
return returnTime
end
local function get_keys_from_Metadata(iam_role,Metadata_url)
local httpc = resty_http:new()
httpc:set_timeout(300) -- set timeout to 300ms
local res,err = httpc:request_uri(Metadata_url .. iam_role,{
ssl_verify = false,keepalive = false
})
if err then
kong.log.err("Could not get keys from Meta-data endpoint")
end
if not res then
kong.log.err("Empty response from Meta-data endpoint")
end
if res.status ~= 200 then
kong.log.err("Not OK (HTTP 200) response from Meta-data endpoint")
end
local body = cjson.decode(res.body)
local expiration = iso8601_to_epoch(body.Expiration) - ngx_time() -- aws keys auto regenerates 5 min before expiration. Maybe have to change this.
return { ["AccessKeyId"] = body.AccessKeyId,["SecretAccessKey"] = body.SecretAccessKey,["Token"] = body.Token },nil,expiration
end
local function get_keys_from_cache(iam_role,Metadata_url,override_ttl,ttl)
if override_ttl then
local cred,err = kong.cache:get(iam_role .. "_cred",{ttl=ttl},get_keys_from_Metadata,iam_role,Metadata_url)
else
local cred,Metadata_url)
end
if err then
kong.log.err("Could not get/put ",err)
end
if cred then
return cred.AccessKeyId,cred.SecretAccessKey,cred.Token
end
return nil
end
local function publish_to_ses(client,request)
local res,err = client:request {
method = "GET",path = request.url,body = request.body,headers = request.headers
}
return res
end
return {
publish = function(conf,body,email_body,notified_key)
local message_body=ngx.escape_uri("This is body")
local email_subject = ngx.escape_uri("This is subject")
local source = ngx.escape_uri("example@gmail.com")
local host = fmt("email.%s.amazonaws.com",conf.aws_region)
local path = "/"
local query = concat({'Version=2010-12-01&Action=SendEmail&Source=',source,'&Destination.ToAddresses.member.1=','&Message.Subject.Data=',email_subject,'&Message.Body.Text.Data=',message_body})
local port = conf.port or AWS_PORT
local aws_key,aws_secret,aws_token
if conf.aws_key == nil and conf.aws_secret == nil and conf.aws_iam_role ~= nil then
if conf.store_creds_in_cache then
aws_key,aws_token = get_keys_from_cache(conf.aws_iam_role,conf.aws_Metadata_url,conf.override_cache_creds_ttl,conf.cache_creds_ttl)
else
local cred,e,ttl = get_keys_from_Metadata(conf.aws_iam_role,conf.aws_Metadata_url)
if cred and e == nil then
aws_key,aws_token = cred.AccessKeyId,cred.Token
end
end
else
aws_key = conf.aws_key
aws_secret = conf.aws_secret
end
local opts = {
region = conf.aws_region,service = "ses",method = "GET",headers = {
["Content-Type"] = "text/plain",},path = path,host = host,port = port,access_key = aws_key,secret_key = aws_secret,query = query
}
if aws_token then
opts["headers"]['X-Amz-Security-Token'] = aws_token
end
local request,err = aws_v4(opts)
if err then
kong.log.err("An unexpected error occurred while signing request according to AWS signature(V4)",err)
end
-- Trigger request
local client = http.new()
client:set_timeout(conf.timeout)
client:connect(host,port)
local ok,err = client:ssl_handshake()
if not ok then
kong.log.err("[SES]An unexpected error occurred while connecting: ",err)
end
local res = publish_to_ses(client,request)
if not res then
if conf.policy == "local" then
service_in_memory:delete(notified_key)
else
res = publish_to_ses(client,request)
end
end
local content = res:read_body()
local ok,err = client:close()
if not ok then
kong.log.err("[SES]Could not close connection :",err)
end
if res.status == 200 then
local MessageId=content:match("MessageId>(.*)</MessageId")
content=cjson.encode({
MessageId=MessageId,})
end
kong.log.info("[SES]Message published: ",content)
end,}
我正在尝试从 AWS EC2 元数据获取凭据
任何小帮助都会对我有很大帮助, 谢谢。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。