カテゴリー
【AWSで構築するサーバレスWebSocket②】 WebSocketAPIにオーソライザーを設定する
※ 当ページには【広告/PR】を含む場合があります。
2021/07/25
WebSocket APIのアクセス保護って?
$ wscat -c wss://[APIのドメインID].[APIのリージョン名].amazonaws.com/[APIをデプロイしたステージ名]
#👆誰でもアクセス可能!
二段重ね
Websocket APIのオーソライザ
1. WebSocketにはHTTPメソッド(GET/POST/...)が無い
ルート選択式
$connect
arn:aws:execute-api:<リージョン>:<アカウント名>:<APIのID>/<ステージ>/$connect
2. パス変数 (event.pathParameters) を使用できない
api1/get
3. event.requestContextのコンテキスト構造が異なる
ws-myapp-auth
nodejs12.x
AWSLambdaBasicExecutionRole
exports.handler = async (event, context, callback) => {
//👇イベントJSON全体を確認したい時に利用
//console.log('Received event:', JSON.stringify(event, null, 2));
const requestContext = event.requestContext;
//👇認証用のヘッダー情報を含む
const headers = event.headers;
//👇認証用のクエリ文字列を含む
const queryStringParameters = event.queryStringParameters;
const tmp = event.methodArn.split(':');
const accountId = tmp[4];
const apiGatewayArnTmp = tmp[5].split('/');
const stage = apiGatewayArnTmp[1];
const authResponse = {};
const condition = {
IpAddress: {}
};
if (headers.HeaderAuth1 === "headerValue1" &&
queryStringParameters.QueryString1 === "queryValue1" &&
stage === "[WebSocket APIのデプロイ先ステージ]" &&
accountId=== "[AWSアカウントID]"
) {
callback(null, generateAllow('me', event.methodArn));
} else {
callback("Unauthorized");
}
};
//👇認証した場合IAMポリシーを付与する
const generatePolicy = (principalId, effect, resource) => {
const authResponse = {
principalId,
//レスポンスに何かキーを付ける場合(オプション)
context: {
"stringKey": "stringval",
"numberKey": 123,
"booleanKey": true
}
};
if (effect && resource) {
const policyDocument = {
Version: '2012-10-17',
Statement: []
};
const statementOne = {
Action: 'execute-api:Invoke',
Effect: effect,
Resource: resource
};
policyDocument.Statement[0] = statementOne;
authResponse.policyDocument = policyDocument;
}
return authResponse;
};
//👇トークンを判定し特定のユーザーを承認する
const generateAllow = (principalId, resource) => {
return generatePolicy(principalId, 'Allow', resource);
};
オーソライザー
[新しいオーソライザーの作成]
ws-app-authorizer
ws-myapp-auth
ヘッダー
クエリ文字列
HeaderAuth1
QueryString1
保存
Lambda呼び出しロール
$connect
ルート
$connect
ルートリクエスト
認可
オーソライザを使った認証テスト
$ wscat -c wss://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/wsDev
error: Unexpected server response: 401
#👇認証ヘッダ+認証クエリともに正しい
$ wscat \
-c 'wss://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/wsDev?QueryString1=queryValue1' \
-H 'HeaderAuth1:headerValue1'
Connected (press CTRL+C to quit)
#👇認証クエリが間違い
$ wscat \
-c 'wss://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/wsDev?QueryString1=hogehoge' \
-H 'HeaderAuth1:headerValue1'
error: Unexpected server response: 401
#👇認証ヘッダーが間違い
$ wscat \
-c 'wss://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/wsDev?QueryString1=queryValue1' \
-H 'HeaderAuth1:hogehoge'
error: Unexpected server response: 401
まとめ
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー