LoginSignup
3
2

More than 5 years have passed since last update.

claudia-js の custom-authorizer を理解する

Last updated at Posted at 2017-01-25

最初に: 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.registerAuthorizertestAuth との関連付けを登録
  • / は誰でもアクセスできる
  • /unlocked にそのまま(Authorizationヘッダ無しで)アクセスすると event.authorizationToken が足りないため、testAuthcallback('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を生成して↑の認証と一緒

たぶんこうなるってだけで、まだ作ってないのでこれから確かめる

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2