最初に: AWS 初心者なので用語の使い方、とくにIAM付近が正しいかよくわかってないです。
概要
- claudia-api-builder で
{ customAuthorizer: 'testAuth' }
と指定すると、それ自身が呼ばれる前に、testAuth
の lambda function が起動する -
testAuth
側では、ログイン成功可否と、そのユーザーのIAM Policy を生成することができる-
execute-api:Invoke
と Resource 該当リソースへのアクセスを許可することで、認証を実現できる
-
Example
https://github.com/claudiajs/example-projects/tree/master/custom-authorizers を読んで理解する。
testAuth として登録される authorizer.js
authorizer.js
/*global exports, console */
var generatePolicy = function (authToken, methodArn) {
'use strict';
var tmp = methodArn.split(':'),
apiGatewayArnTmp = tmp[5].split('/'),
awsAccountId = tmp[4],
region = tmp[3],
restApiId = apiGatewayArnTmp[0],
stage = apiGatewayArnTmp[1];
return {
'principalId': authToken.split('-')[0],
'policyDocument': {
'Version': '2012-10-17',
'Statement': [{
'Effect': 'Allow',
'Action': [
'execute-api:Invoke'
],
'Resource': [
'arn:aws:execute-api:' + region + ':' + awsAccountId + ':' + restApiId + '/' + stage + '/GET/unlocked'
]
}]
}
};
};
exports.auth = function testAuth(event, context, callback) {
'use strict';
console.log('got event', event);
/*
* {
* "type":"TOKEN",
* "authorizationToken":"<Incoming bearer token>",
* "methodArn":"arn:aws:execute-api:<Region id>:<Account id>:<API id>/<Stage>/<Method>/<Resource path>"
* }
*/
if (event && event.authorizationToken && event.methodArn) {
callback(null, generatePolicy(event.authorizationToken, event.methodArn));
} else {
callback('Unauthorized');
}
};
- 認証できるかの判定
- 認証できた場合のIAM Policy
次に、それを使用する claudia-api-builder
index.js
/*global require, module */
var ApiBuilder = require('claudia-api-builder'),
api = new ApiBuilder();
module.exports = api;
api.registerAuthorizer('testAuth', {
lambdaName: 'testAuth',
lambdaVersion: true
});
api.get('/', function () {
'use strict';
return 'OK';
});
api.get('/locked', function () {
'use strict';
return 'NOT-OK';
}, { customAuthorizer: 'testAuth' });
api.get('/unlocked', function (request) {
'use strict';
return 'OK for ' + request.context.authorizerPrincipalId;
}, { customAuthorizer: 'testAuth' });
-
api.registerAuthorizer
でtestAuth
との関連付けを登録 -
/
は誰でもアクセスできる -
/unlocked
にそのまま(Authorizationヘッダ無しで)アクセスすると event.authorizationToken が足りないため、testAuth
でcallback('Unauthorized')
でアクセス権が付与されず、落ちる -
/unlocked
にAuthorization ヘッダ付きでアクセスすると ポリシーが付与され、アクセスに成功する-
curl -i https://<your-hash>.execute-api.ap-northeast-1.amazonaws.com/dev/unlocked -H 'Authorization: Bob-123'
=>Ok for Bob-123
-/locked
は認証成功してもIAMポリシーが付与されないので、アクセスできない
-
実際の使い方を考える
DynamoDBをバックエンドに普通の認証系を作りたい
-
/register
で username/password を送って、DynamoDBのusersテーブルへ書き込み、accessToken を生成して書き込み、クライアントへ返す - クライアントからaccessToken をHeaderに入れてリクエストをすると、authが通る
-
/logout
で accessToken 破棄 -
/login
で username/password で accessToken 再生成
TwitterのOAuthを通したい
- TwitterのOAuthフローに飛ばす
- OAuth認可のコールバックをLambdaでうける
- nodeのoauthライブラリを使ってOAuthの検証/処理を進め、TwitterのaccessTokenを手に入れる
- あとはアプリ用AccessTokenを生成して↑の認証と一緒
たぶんこうなるってだけで、まだ作ってないのでこれから確かめる