一、背景
上一篇文章是基础版,这篇文章增加授权方
二、创建授权方
1、新建lambda函数,来验证授权方,运行时选择 node.js 16.x
代码如下:当header中account和password匹配上,则allow,否则deny
exports.handler = function(event, context, callback) {
console.log('received event:', json.stringify(event, null, 2));
// a simple request-based authorizer example to demonstrate how to use request
// parameters to allow or deny a request. in this example, a request is
// authorized if the client-supplied headerauth1 header, querystring1
// query parameter, and stage variable of stagevar1 all match
// specified values of 'headervalue1', 'queryvalue1', and 'stagevalue1',
// respectively.
// retrieve request parameters from the lambda function input:
var headers = event.headers;
var querystringparameters = event.querystringparameters;
var pathparameters = event.pathparameters;
var stagevariables = event.stagevariables;
// parse the input for the parameter values
var tmp = event.methodarn.split(':');
var apigatewayarntmp = tmp[5].split('/');
var awsaccountid = tmp[4];
var region = tmp[3];
var restapiid = apigatewayarntmp[0];
var stage = apigatewayarntmp[1];
var method = apigatewayarntmp[2];
var resource = '/'; // root resource
if (apigatewayarntmp[3]) {
resource += apigatewayarntmp[3];
}
// perform authorization to return the allow policy for correct parameters and
// the 'unauthorized' error, otherwise.
var authresponse = {};
var condition = {};
condition.ipaddress = {};
if (headers.account === ""
&& headers.password === "") {
callback(null, generateallow('me', event.methodarn));
}else {
callback("unauthorized");
}
}
// help function to generate an iam policy
var generatepolicy = function(principalid, effect, resource) {
// required output:
var authresponse = {};
authresponse.principalid = principalid;
if (effect && resource) {
var policydocument = {};
policydocument.version = '2012-10-17'; // default version
policydocument.statement = [];
var statementone = {};
statementone.action = 'execute-api:invoke'; // default action
statementone.effect = effect;
statementone.resource = resource;
policydocument.statement[0] = statementone;
authresponse.policydocument = policydocument;
}
// optional output with custom properties of the string, number or boolean type.
authresponse.context = {
"account": '',
"password": '',
"booleankey": true
};
return authresponse;
}
var generateallow = function(principalid, resource) {
return generatepolicy(principalid, 'allow', resource);
}
var generatedeny = function(principalid, resource) {
return generatepolicy(principalid, 'deny', resource);
}
2、创建授权方
授权方名称
类型:选择lambda
lambda函数:填写刚创建好的lambda函数名称
lambda调用角色:填写调用lambda函数的角色
lambda事件负载:选择请求
身份来源:选择标头,添加account和password
授权缓存:取消启用
三、配置授权方
选择 添加授权方的路径资源方法中的方法请求
授权选择配置好的授权方名称
请求验证程序:无
需要api密钥:否
http请求标头:将account和password配置进来
三、测试api
测试通过两种方式:①postman ②python代码
获取url链接
1、postman
进入postman,添加put请求,复制url链接,在其后添加上传到s3的路径,在headers中添加account和password,点击send,即可在下方看到请求结果
2、python代码:在headers中添加account和password
import requests
def call_api(_url, _headers, _files):
res = requests.put(_url, data=_files, headers=_headers)
return res
def unload_s3(local_file_name,s3_file_name):
# api gateway call url
url_ip = ""
# generate the url
url = url_ip + s3_file_name
# the file on your computer
uploadfile = open(local_file_name, "rb")
# request headers
headers = {"account": "",
"password": ""}
# call the api2s3 method
res = call_api(url, headers, uploadfile)
# print the result
if res.ok:
return ("upload completed successfully!")
else:
return ("upload failed!")
if __name__ == '__main__':
# local file name
local_file_name = ''
# s3 file_name to upload
s3_file_name = ''
unload_s3(local_file_name,s3_file_name)
四、通过cloudformation创建api
yaml文件如下
awstemplateformatversion: '2010-09-09'
description : template to provision etl workflow for api gateway
parameters:
region:
description: 'specify the region for resource.'
type: string
default: ase1
createdate:
type: string
default: '2022-07-15'
iteration:
type: string
description: 'specify the iteration for lambda.'
default: '001'
s3iteration:
type: string
description: 'specify the iteration for s3'
default: '001'
iamiteration:
type: string
description: 'specify the iteration for iam roles.'
default: '001'
resources:
apigatewayrestapi:
type: aws::apigateway::restapi
properties:
name: api-uploads3-{iteration}
binarymediatypes:
- "*/*"
description: create api to load file to s3
mode: overwrite
endpointconfiguration:
types:
- regional
minimumcompressionsize: 0
apigatewayauthorizer:
type: aws::apigateway::authorizer
properties:
authorizercredentials: "arn:aws:iam::role/iamr-replication-${iamiteration}"
authorizerresultttlinseconds : 0
authorizeruri: "arn:aws:apigateway:${aws::region}:lambda:path/2015-03-31/functions/arn:aws:lambda:lamb-apigw-authorizer-${s3iteration}/invocations"
type : request
authtype: custom
restapiid:
!ref apigatewayrestapi
name: auth-request
identitysource : method.request.header.account,method.request.header.password
apigatewayresourcefolder:
type: aws::apigateway::resource
properties:
restapiid:
!ref apigatewayrestapi
pathpart: "{folder}"
parentid: !getatt
- apigatewayrestapi
- rootresourceid
apigatewayresourcepartition:
type: aws::apigateway::resource
properties:
restapiid:
!ref apigatewayrestapi
pathpart: "{partition}"
parentid:
!ref apigatewayresourcetablename
apigatewayresourcetablename:
type: aws::apigateway::resource
properties:
restapiid:
!ref apigatewayrestapi
pathpart: "{tablename}"
parentid:
!ref apigatewayresourcefolder
apigatewayresourcefilename:
type: aws::apigateway::resource
properties:
restapiid:
!ref apigatewayrestapi
pathpart: "{filename}"
parentid:
!ref apigatewayresourcepartition
apigatewaymethodtablename:
type: aws::apigateway::method
properties:
authorizerid:
!ref apigatewayauthorizer
authorizationtype: custom
requestparameters: {
"method.request.path.folder": true,
"method.request.path.tablename": true,
"method.request.header.account": true,
"method.request.header.password": true
}
httpmethod: put
methodresponses:
- statuscode: 200
responsemodels:
application/json: empty
restapiid:
!ref apigatewayrestapi
resourceid: !getatt
- apigatewayresourcetablename
- resourceid
integration:
type: aws
credentials: "arn:aws:iam::role/iamr-replication-${iamiteration}"
integrationhttpmethod: put
integrationresponses:
- statuscode: 200
passthroughbehavior: when_no_match
uri: "arn:aws:apigateway:${aws::region}:s3:path/s3-raw-${iteration}/{folder}/{tablename}"
requestparameters: {
"integration.request.path.folder" : "method.request.path.folder",
"integration.request.path.tablename" : "method.request.path.tablename"
}
apigatewaymethodpartition:
type: aws::apigateway::method
properties:
authorizerid:
!ref apigatewayauthorizer
authorizationtype: custom
requestparameters: {
"method.request.path.folder": true,
"method.request.path.tablename": true,
"method.request.path.partition": true,
"method.request.header.account": true,
"method.request.header.password": true
}
httpmethod: put
methodresponses:
- statuscode: 200
responsemodels:
application/json: empty
restapiid:
!ref apigatewayrestapi
resourceid: !getatt
- apigatewayresourcepartition
- resourceid
integration:
type: aws
credentials: "arn:aws:iam::role/iamr-replication-${iamiteration}"
integrationhttpmethod: put
integrationresponses:
- statuscode: 200
passthroughbehavior: when_no_match
uri: "arn:aws:apigateway:${aws::region}:s3:path/s3-raw-${iteration}/{folder}/{tablename}/{partition}"
requestparameters: {
"integration.request.path.partition" : "method.request.path.partition",
"integration.request.path.folder" : "method.request.path.folder",
"integration.request.path.tablename" : "method.request.path.tablename"
}
apigatewaymethodfilename:
type: aws::apigateway::method
properties:
authorizerid:
!ref apigatewayauthorizer
authorizationtype: custom
requestparameters: {
"method.request.path.folder": true,
"method.request.path.tablename": true,
"method.request.path.partition": true,
"method.request.path.filename": true,
"method.request.header.account": true,
"method.request.header.password": true
}
httpmethod: put
methodresponses:
- statuscode: 200
responsemodels:
application/json: empty
restapiid:
!ref apigatewayrestapi
resourceid: !getatt
- apigatewayresourcefilename
- resourceid
integration:
type: aws
credentials: "arn:aws:iam::role/iamr-replication-${iamiteration}"
integrationhttpmethod: put
integrationresponses:
- statuscode: 200
passthroughbehavior: when_no_match
uri: "arn:aws:apigateway:${aws::region}:s3:path/s3-raw-${iteration}/{folder}/{tablename}/{partition}/{filename}"
requestparameters: {
"integration.request.path.partition" : "method.request.path.partition",
"integration.request.path.filename" : "method.request.path.filename",
"integration.request.path.folder" : "method.request.path.folder",
"integration.request.path.tablename" : "method.request.path.tablename"
}
apigatewaydeploymentv3:
dependson: apigatewaymethodfilename
type: aws::apigateway::deployment
properties:
restapiid:
!ref apigatewayrestapi
stagename : v3
permissiontoinvokelambda:
type: aws::lambda::permission
properties:
functionname: lamb-apigw-authorizer-${iteration}
action: "lambda:invokefunction"
principal: "apigateway.amazonaws.com"
sourcearn: !sub
- "arn:aws:execute-api:${aws::region}:${aws::accountid}:${apiid}/authorizers/${authorizerid}"
- apiid:
!ref apigatewayrestapi
authorizerid:
!ref apigatewayauthorizer
outputs:
rootresourceid:
value: !getatt apigatewayrestapi.rootresourceid
authorizerid:
value: !getatt apigatewayauthorizer.authorizerid
发表评论