Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

Outline

cloudcomponents Logo

@cloudcomponents/cdk-cloudfront-authorization

Build Status cdkdx typescript python Mentioned in Awesome CDK

CloudFront with Cognito authentication using Lambda@Edge

This construct is based on https://github.com/aws-samples/cloudfront-authorization-at-edge.

Install

TypeScript/JavaScript:

npm i @cloudcomponents/cdk-cloudfront-authorization 

Python:

pip install cloudcomponents.cdk-cloudfront-authorization 

How to use SPA

import { Construct, Stack, StackProps } from '@aws-cdk/core';
import { UserPool } from '@aws-cdk/aws-cognito';
import {
  SpaAuthorization,
  SpaDistribution,
} from '@cloudcomponents/cdk-cloudfront-authorization';

export class CloudFrontAuthorizationStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const userPool = new UserPool(this, 'UserPool', {
      selfSignUpEnabled: false,
      userPoolName: 'cloudfront-authorization-userpool',
    });

    // UserPool must have a domain!
    userPool.addDomain('Domain', {
      cognitoDomain: {
        domainPrefix: 'cloudcomponents',
      },
    });

    const authorization = new SpaAuthorization(this, 'Authorization', {
      userPool,
    });

    new SpaDistribution(this, 'Distribution', {
      authorization,
    });
  }
}

How to use StaticSite

import { Construct, Stack, StackProps } from '@aws-cdk/core';
import { UserPool } from '@aws-cdk/aws-cognito';
import {
  StaticSiteAuthorization,
  StaticSiteDistribution,
} from '@cloudcomponents/cdk-cloudfront-authorization';

export class CloudFrontAuthorizationStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const userPool = new UserPool(this, 'UserPool', {
      selfSignUpEnabled: false,
      userPoolName: 'cloudfront-authorization-userpool',
    });

    // UserPool must have a domain!
    userPool.addDomain('Domain', {
      cognitoDomain: {
        domainPrefix: 'cloudcomponents',
      },
    });

    const authorization = new StaticSiteAuthorization(this, 'Authorization', {
      userPool,
    });

    new StaticSiteDistribution(this, 'Distribution', {
      authorization,
    });
  }
}

Legacy CloudFrontWebDistribution

import { CloudFrontWebDistribution, OriginAccessIdentity } from '@aws-cdk/aws-cloudfront';
import { UserPool } from '@aws-cdk/aws-cognito';
import { Bucket } from '@aws-cdk/aws-s3'
import { Construct, Stack, StackProps, RemovalPolicy } from '@aws-cdk/core';
import { SpaAuthorization } from '@cloudcomponentscdk-cloudfront-authorization';

export class CloudFrontAuthorizationStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const userPool = new UserPool(this, 'UserPool', {
      selfSignUpEnabled: false,
      userPoolName: 'cloudfront-authorization-userpool',
    });

    userPool.addDomain('Domain', {
      cognitoDomain: {
        domainPrefix: 'cloudcomponents',
      },
    });

    const authorization = new SpaAuthorization(this, 'Authorization', {
      userPool,
    });

    const bucket = new Bucket(this, 'Bucket', {
      autoDeleteObjects: true,
      removalPolicy: RemovalPolicy.DESTROY,
    });

    const originAccessIdentity = new OriginAccessIdentity(this, 'OriginAccessIdentity', {
      comment: `CloudFront OriginAccessIdentity for ${bucket.bucketName}`,
    });

    new CloudFrontWebDistribution(this, 'Distribution', {
      originConfigs: [
        {
          s3OriginSource: {
            s3BucketSource: bucket,
            originAccessIdentity,
          },
          behaviors: [authorization.createLegacyDefaultBehavior(), ...authorization.createLegacyAdditionalBehaviors()],
        },
      ],
    });
  }
}

Identity Providers

Identity providers can be specified in the authorization object. To make sure that the user pool client is created after the identity provider, please specify a dependency using "addDependency".

const identityProvider = UserPoolIdentityProviderAmazon(this, "IdentityProvider", {
  // ...
})
const authorization = new SpaAuthorization(this, 'Authorization_SPA', {
  // ...
  identityProviders: [cognito.UserPoolClientIdentityProvider.AMAZON],
};
authorization.userPoolClient.node.addDependency(identityProvider);

SPA mode vs. Static Site mode

SPA

  • User Pool client does not use a client secret
  • The cookies with JWT's are not "http only", so that they can be read and used by the SPA (e.g. to display the user name, or to refresh tokens)
  • 404's (page not found on S3) will return index.html, to enable SPA-routing

Static Site

  • Enforce use of a client secret
  • Set cookies to be http only by default (unless you've provided other cookie settings explicitly)
  • No special error handling

API Reference

See API.md.

Example

See more complete examples.

License

MIT

Morty Proxy This is a proxified and sanitized view of the page, visit original site.