-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(cognito): add SAML user pool identity provider #21879
Merged
+956
−1
Merged
Changes from 10 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
bd2ab7f
Add SAML user pool identity provider construct
ktfleming ae1e2c5
Update Cognito README with SAML IdP support
ktfleming 5ce936a
Ignore props-physical-name awslint rule for SAML props
ktfleming 5126400
Add unit tests for SAML user pool identity provider
ktfleming 8394f9f
Add integ test for SAML user pool identity provider
ktfleming 265c785
Use Names.uniqueResourceName instead of Names.uniqueId
ktfleming 6946c0b
Extract validateName function
ktfleming b3f44e1
Add provider name length restrictions to docstring
ktfleming afda2ff
Rework how SAML metadata is specified
ktfleming 62e0da1
Update SAML IdP tests
ktfleming 36965e7
Rework how SAML metadata is provided
ktfleming af574c0
Merge branch 'main' into cognito-saml-idp
mergify[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
packages/@aws-cdk/aws-cognito/lib/user-pool-idps/saml.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { Names, Token } from '@aws-cdk/core'; | ||
import { Construct } from 'constructs'; | ||
import { CfnUserPoolIdentityProvider } from '../cognito.generated'; | ||
import { UserPoolIdentityProviderProps } from './base'; | ||
import { UserPoolIdentityProviderBase } from './private/user-pool-idp-base'; | ||
|
||
/** | ||
* Properties to initialize UserPoolIdentityProviderSaml. | ||
*/ | ||
export interface UserPoolIdentityProviderSamlProps extends UserPoolIdentityProviderProps { | ||
/** | ||
* The name of the provider. Must be between 3 and 32 characters. | ||
* | ||
* @default - the unique ID of the construct | ||
*/ | ||
readonly name?: string; | ||
|
||
/** | ||
* Identifiers | ||
* | ||
* Identifiers can be used to redirect users to the correct IdP in multitenant apps. | ||
* | ||
* @default - no identifiers used | ||
*/ | ||
readonly identifiers?: string[] | ||
|
||
/** | ||
* The SAML metadata file type. | ||
*/ | ||
readonly metadataType: UserPoolIdentityProviderSamlMetadataType; | ||
|
||
/** | ||
* The SAML metadata content. | ||
* If metadataType is set to URL, this should be the metadata URL. | ||
* If metadataType is set to FILE, this should be the metadata file contents. | ||
*/ | ||
readonly metadataContent: string; | ||
|
||
/** | ||
* Whether to enable the "Sign-out flow" feature. | ||
* | ||
* @default - false | ||
*/ | ||
readonly idpSignout?: boolean; | ||
} | ||
|
||
/** | ||
* Metadata types that can be used for a SAML user pool identity provider. | ||
*/ | ||
export enum UserPoolIdentityProviderSamlMetadataType { | ||
/** Metadata provided via a URL. */ | ||
URL = 'url', | ||
|
||
/** Metadata provided via the contents of a file. */ | ||
FILE = 'file', | ||
} | ||
|
||
/** | ||
* Represents a identity provider that integrates with SAML. | ||
* @resource AWS::Cognito::UserPoolIdentityProvider | ||
*/ | ||
export class UserPoolIdentityProviderSaml extends UserPoolIdentityProviderBase { | ||
public readonly providerName: string; | ||
|
||
constructor(scope: Construct, id: string, props: UserPoolIdentityProviderSamlProps) { | ||
super(scope, id, props); | ||
|
||
this.validateName(props.name); | ||
|
||
const providerDetails: Record<string, string | boolean> = { | ||
IDPSignout: props.idpSignout ?? false, | ||
}; | ||
|
||
if (props.metadataType === UserPoolIdentityProviderSamlMetadataType.URL) { | ||
providerDetails.MetadataURL = props.metadataContent; | ||
} else if (props.metadataType === UserPoolIdentityProviderSamlMetadataType.FILE) { | ||
providerDetails.MetadataFile = props.metadataContent; | ||
} | ||
|
||
const resource = new CfnUserPoolIdentityProvider(this, 'Resource', { | ||
userPoolId: props.userPool.userPoolId, | ||
providerName: this.getProviderName(props.name), | ||
providerType: 'SAML', | ||
providerDetails, | ||
idpIdentifiers: props.identifiers, | ||
attributeMapping: super.configureAttributeMapping(), | ||
}); | ||
|
||
this.providerName = super.getResourceNameAttribute(resource.ref); | ||
} | ||
|
||
private getProviderName(name?: string): string { | ||
if (name) { | ||
this.validateName(name); | ||
return name; | ||
} | ||
|
||
const uniqueName = Names.uniqueResourceName(this, { | ||
maxLength: 32, | ||
}); | ||
|
||
if (uniqueName.length < 3) { | ||
return `${uniqueName}saml`; | ||
} | ||
|
||
return uniqueName; | ||
} | ||
|
||
private validateName(name?: string) { | ||
if (name && !Token.isUnresolved(name) && (name.length < 3 || name.length > 32)) { | ||
throw new Error(`Expected provider name to be between 3 and 32 characters, received ${name} (${name.length} characters)`); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
packages/@aws-cdk/aws-cognito/test/integ.user-pool-idp.saml.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { App, CfnOutput, RemovalPolicy, Stack } from '@aws-cdk/core'; | ||
import { IntegTest } from '@aws-cdk/integ-tests'; | ||
import { Construct } from 'constructs'; | ||
import { UserPool, UserPoolIdentityProviderSaml, UserPoolIdentityProviderSamlMetadataType } from '../lib'; | ||
|
||
class TestStack extends Stack { | ||
constructor(scope: Construct, id: string) { | ||
super(scope, id); | ||
const userpool = new UserPool(this, 'pool', { | ||
removalPolicy: RemovalPolicy.DESTROY, | ||
}); | ||
|
||
new UserPoolIdentityProviderSaml(this, 'cdk', { | ||
userPool: userpool, | ||
name: 'cdk', | ||
metadataType: UserPoolIdentityProviderSamlMetadataType.URL, | ||
metadataContent: 'https://fujifish.github.io/samling/public/metadata.xml', | ||
}); | ||
|
||
const client = userpool.addClient('client'); | ||
|
||
const domain = userpool.addDomain('domain', { | ||
cognitoDomain: { | ||
domainPrefix: 'cdk-test-pool', | ||
}, | ||
}); | ||
|
||
new CfnOutput(this, 'SignInLink', { | ||
value: domain.signInUrl(client, { | ||
redirectUri: 'https://example.com', | ||
}), | ||
}); | ||
} | ||
} | ||
|
||
const app = new App(); | ||
const testCase = new TestStack(app, 'integ-user-pool-identity-provider-saml-stack'); | ||
|
||
new IntegTest(app, 'integ-user-pool-identity-provider-saml-test', { | ||
testCases: [testCase], | ||
}); |
1 change: 1 addition & 0 deletions
1
packages/@aws-cdk/aws-cognito/test/user-pool-idp.saml.integ.snapshot/cdk.out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"version":"21.0.0"} |
19 changes: 19 additions & 0 deletions
19
...ser-pool-idp.saml.integ.snapshot/integ-user-pool-identity-provider-saml-stack.assets.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"version": "21.0.0", | ||
"files": { | ||
"6f6f07786415216f13b738979cec5ad81dbab3283fae83b99324965935cc1d60": { | ||
"source": { | ||
"path": "integ-user-pool-identity-provider-saml-stack.template.json", | ||
"packaging": "file" | ||
}, | ||
"destinations": { | ||
"current_account-current_region": { | ||
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", | ||
"objectKey": "6f6f07786415216f13b738979cec5ad81dbab3283fae83b99324965935cc1d60.json", | ||
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" | ||
} | ||
} | ||
} | ||
}, | ||
"dockerImages": {} | ||
} |
145 changes: 145 additions & 0 deletions
145
...r-pool-idp.saml.integ.snapshot/integ-user-pool-identity-provider-saml-stack.template.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
{ | ||
"Resources": { | ||
"pool056F3F7E": { | ||
"Type": "AWS::Cognito::UserPool", | ||
"Properties": { | ||
"AccountRecoverySetting": { | ||
"RecoveryMechanisms": [ | ||
{ | ||
"Name": "verified_phone_number", | ||
"Priority": 1 | ||
}, | ||
{ | ||
"Name": "verified_email", | ||
"Priority": 2 | ||
} | ||
] | ||
}, | ||
"AdminCreateUserConfig": { | ||
"AllowAdminCreateUserOnly": true | ||
}, | ||
"EmailVerificationMessage": "The verification code to your new account is {####}", | ||
"EmailVerificationSubject": "Verify your new account", | ||
"SmsVerificationMessage": "The verification code to your new account is {####}", | ||
"VerificationMessageTemplate": { | ||
"DefaultEmailOption": "CONFIRM_WITH_CODE", | ||
"EmailMessage": "The verification code to your new account is {####}", | ||
"EmailSubject": "Verify your new account", | ||
"SmsMessage": "The verification code to your new account is {####}" | ||
} | ||
}, | ||
"UpdateReplacePolicy": "Delete", | ||
"DeletionPolicy": "Delete" | ||
}, | ||
"poolclient2623294C": { | ||
"Type": "AWS::Cognito::UserPoolClient", | ||
"Properties": { | ||
"UserPoolId": { | ||
"Ref": "pool056F3F7E" | ||
}, | ||
"AllowedOAuthFlows": [ | ||
"implicit", | ||
"code" | ||
], | ||
"AllowedOAuthFlowsUserPoolClient": true, | ||
"AllowedOAuthScopes": [ | ||
"profile", | ||
"phone", | ||
"email", | ||
"openid", | ||
"aws.cognito.signin.user.admin" | ||
], | ||
"CallbackURLs": [ | ||
"https://example.com" | ||
], | ||
"SupportedIdentityProviders": [ | ||
{ | ||
"Ref": "cdk52888317" | ||
}, | ||
"COGNITO" | ||
] | ||
} | ||
}, | ||
"pooldomain430FA744": { | ||
"Type": "AWS::Cognito::UserPoolDomain", | ||
"Properties": { | ||
"Domain": "cdk-test-pool", | ||
"UserPoolId": { | ||
"Ref": "pool056F3F7E" | ||
} | ||
} | ||
}, | ||
"cdk52888317": { | ||
"Type": "AWS::Cognito::UserPoolIdentityProvider", | ||
"Properties": { | ||
"ProviderName": "cdk", | ||
"ProviderType": "SAML", | ||
"UserPoolId": { | ||
"Ref": "pool056F3F7E" | ||
}, | ||
"ProviderDetails": { | ||
"IDPSignout": false, | ||
"MetadataURL": "https://fujifish.github.io/samling/public/metadata.xml" | ||
} | ||
} | ||
} | ||
}, | ||
"Outputs": { | ||
"SignInLink": { | ||
"Value": { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"https://", | ||
{ | ||
"Ref": "pooldomain430FA744" | ||
}, | ||
".auth.", | ||
{ | ||
"Ref": "AWS::Region" | ||
}, | ||
".amazoncognito.com/login?client_id=", | ||
{ | ||
"Ref": "poolclient2623294C" | ||
}, | ||
"&response_type=code&redirect_uri=https://example.com" | ||
] | ||
] | ||
} | ||
} | ||
}, | ||
"Parameters": { | ||
"BootstrapVersion": { | ||
"Type": "AWS::SSM::Parameter::Value<String>", | ||
"Default": "/cdk-bootstrap/hnb659fds/version", | ||
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" | ||
} | ||
}, | ||
"Rules": { | ||
"CheckBootstrapVersion": { | ||
"Assertions": [ | ||
{ | ||
"Assert": { | ||
"Fn::Not": [ | ||
{ | ||
"Fn::Contains": [ | ||
[ | ||
"1", | ||
"2", | ||
"3", | ||
"4", | ||
"5" | ||
], | ||
{ | ||
"Ref": "BootstrapVersion" | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." | ||
} | ||
] | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
packages/@aws-cdk/aws-cognito/test/user-pool-idp.saml.integ.snapshot/integ.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"version": "21.0.0", | ||
"testCases": { | ||
"integ-user-pool-identity-provider-saml-test/DefaultTest": { | ||
"stacks": [ | ||
"integ-user-pool-identity-provider-saml-stack" | ||
], | ||
"assertionStack": "integ-user-pool-identity-provider-saml-test/DefaultTest/DeployAssert", | ||
"assertionStackName": "integuserpoolidentityprovidersamltestDefaultTestDeployAssert97F09C26" | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...snapshot/integuserpoolidentityprovidersamltestDefaultTestDeployAssert97F09C26.assets.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"version": "21.0.0", | ||
"files": { | ||
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { | ||
"source": { | ||
"path": "integuserpoolidentityprovidersamltestDefaultTestDeployAssert97F09C26.template.json", | ||
"packaging": "file" | ||
}, | ||
"destinations": { | ||
"current_account-current_region": { | ||
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", | ||
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", | ||
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" | ||
} | ||
} | ||
} | ||
}, | ||
"dockerImages": {} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure this will run afoul of jsii. The union operator doesn't translate well in most cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the rework of how metadata is provided in 36965e7, this union operator has gone away.