👻
CognitoでユーザごとにS3フォルダアクセス制御をする
検索するとすでに色々情報があるので、こちらでは2023/07/05時点のCDKの実装について紹介したいと思います。
UserプールはL2 Constructがすでに用意されていますが、IDプールはまだalpha版です。モジュールが安定したら aws-cognito
ライブラリに入るようです。そうすると、ちょっとごちゃごちゃしているauthenticatedRoleあたりもスッキリできるのかなぁと期待しています。
ポイントは
- S3 Bucketの CORS設定
- IDプールのauthenticatedRoleにポリシーを設定する
あたりでしょうか。
import { Duration, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib';
import * as cognito from 'aws-cdk-lib/aws-cognito';
import { Construct } from 'constructs';
import { IdentityPool, UserPoolAuthenticationProvider } from '@aws-cdk/aws-cognito-identitypool-alpha';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';
import { CfnOutput } from 'aws-cdk-lib';
export class CognitoS3Stack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const bucket = new s3.Bucket(this, 'bucket0705', {
cors: [{
allowedHeaders: ['*'],
allowedMethods: [s3.HttpMethods.GET, s3.HttpMethods.PUT, s3.HttpMethods.POST, s3.HttpMethods.DELETE, s3.HttpMethods.HEAD],
allowedOrigins: ['*'],
exposedHeaders: ["ETag"]
}],
encryption: s3.BucketEncryption.KMS_MANAGED,
bucketKeyEnabled: true,
removalPolicy: RemovalPolicy.DESTROY,
autoDeleteObjects: true
})
const userPool = new cognito.UserPool(this, 'userPool0705', {
userPoolName: 'userPool0705',
signInCaseSensitive: false,
selfSignUpEnabled: true,
userVerification: {
emailSubject: 'Verify your email',
emailBody: 'Please verify your email by clicking on the following link: {####}',
emailStyle: cognito.VerificationEmailStyle.CODE,
smsMessage: 'Your verification code is {####}'
},
signInAliases: { email: true },
autoVerify: { email: true },
keepOriginal: { email: true },
mfa: cognito.Mfa.OFF,
passwordPolicy: {
minLength: 8,
requireLowercase: true,
requireUppercase: true,
requireDigits: true,
requireSymbols: true,
tempPasswordValidity: Duration.days(1)
},
standardAttributes: {
email: { required: true },
},
email: cognito.UserPoolEmail.withCognito(),
removalPolicy: RemovalPolicy.DESTROY
})
const client = userPool.addClient('userPoolClient0705', {})
const idPool = new IdentityPool(this, 'identityPool0705', {
identityPoolName: 'identityPool0705',
authenticationProviders: {
userPools: [new UserPoolAuthenticationProvider({userPool})]
},
allowClassicFlow: true,
allowUnauthenticatedIdentities: false,
})
const s3Statement = new iam.PolicyStatement({
actions: [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
resources: [
bucket.bucketArn + "/private/${cognito-identity.amazonaws.com:sub}/*"
],
effect: iam.Effect.ALLOW
})
const cognitoStatement = new iam.PolicyStatement({
actions: [
"cognito-identity:GetCredentialsForIdentity"
],
resources: [
"*"
],
effect: iam.Effect.ALLOW
})
const authenticatedPolicy = new iam.Policy(this, 'authenticatedPolicy0705', {
policyName: 'authenticatedPolicy0705',
statements: [cognitoStatement,s3Statement]
})
idPool.authenticatedRole.attachInlinePolicy(authenticatedPolicy)
const userPoolId = userPool.userPoolId
const identityPoolId = idPool.identityPoolId
new CfnOutput(this, 'userPoolId', {value: userPoolId})
new CfnOutput(this, 'identityPoolId', {value: identityPoolId})
new CfnOutput(this, 's3Bucket', {value: bucket.bucketName})
}
}
Roleを作って idPool.authenticatedRole
に設定しようとしたらうまくいかず、まずIDプールを作って、そのあとでポリシーを追加する形になっています。
これらの記事を参考にさせていただきました。ありがとうございます。
Discussion