Cognito PreSignup Lambda to create user internally first and then in userpool - authentication

We have an existing system where we create the user id (db) internally and use it across db tables as refrential integrity. We are looking to move to Cognito and Api Gateway for authentication and authorization flow. However, we would like to retain the existing identity (user id in db) internally once we authenticate at Api Gateway using Cognito. To do this, we are thinking of using Pre-Signup Lambda trigger to first create the user in our system via that and then Cognito will create the user in the userpool. This way we can associate custom attribute (user id) information using Pre-Token generation lambda which will be passed to Api Gateway with ID Token.
Is this the right approach to create the user first in our system (via Pre-Signup lambda) and then in Cognito?

Related

How to disable AWS Cognito User Pool account created via Identity Provider?

Any Cognito User Pool gurus out there? I've been using Cognito for a while now but this one has me a bit stumped.
We allow users to sign up and sign in using social accounts like Facebook which are set up as Identity Providers in the User Pool.
Users need to complete a custom registration form before they can use the main app - we don't use the hosted UI for login or signup
One step of the custom registration process allows the user to indicate which social provider then want to use
This allows us to pull back the users email, first and last names from the social provider which is great - we use a cognito client and callback to do this currently
But in doing so, this provisions a user within the Userpool before the registration process is complete - in fact this makes sense- in order for Cognito to provide us the user info it needs to have called into the social providers /userinfo endpoint to populate the user data
So, the issue we now have is that whilst the user is half way through the registration process I have a confirmed user account - eg. before the user has completed the registration process
This is an issue because a user could sign into the the app using their social login without ever have completed the registration process
So as I see it I have two options:
PostConfirmation Lambda trigger which uses the cognito-idp SDK to disable the user just after it was confirmed
Don't use Cognito to obtain the user info like firstname, lastname, email, picture etc - however this would require us to write a solution for every current and future social provider which isn't something I'm keen on
Am I missing something obvious?
Thanks in advance!
I would say PostConfirmation Lambda trigger is a good approach - however instead use adminDisableProviderForUser to disable the user from signing in with the specified external (SAML or social) identity provider
adminDisableProviderForUser
You can later call adminLinkProviderForUser to link the existing user account in the user pool to the external identity provider.
adminLinkProviderForUser
An alternative solution is to prevent the user from signing in if they have not fully completed the registration process via a Pre Authentication Lambda Trigger checking for a unique identifier with respect to your completed registration process
The simplest solution in the end for us was a Pre Token Generation Trigger in Cognito like this:
exports.handler = async (event) => {
if(event.triggerSource==="TokenGeneration_HostedAuth") {
//check db/api etc to see if we have a valid registration stored for user
if(!hasCompletedRegistration) {
//throw auth exception which we can catch on the frontend to inform user
throw new Error("REGISTRATION_NOT_COMPLETE")
}
}
return event
};
For username/password sign ins the TriggerSource will be TokenGeneration_Authentication
For federated/social sign ins the TriggerSource will be TokenGeneration_HostedAuth

WSO2 Identity Server(5.9.0) - is it possible to access users from jdbc user store using embedded read only ldap?

The Requirement is maintaining single JDBC(postgreSQL) user store for the below applications,
Create a user using SCIM api in to wso2-is.
Authenticate my microservices using oauth2 client of service provider.
Integrate WSO2-IS embedded read only LDAP for BPM(Camunda) application authentication and authorization.
I am able to do the first and second points and created a single JDBC user store for users.
For the third point, not able to get the users from JDBC user store using embedded read only LDAP.
Can you help me in this flow, is there any way available in wso2-is to achieve this requirement?
You can use the create a Read-only LDAP secondary user store for LDAP and use it for the BPM(Camunda) application authentication and authorization. You can find more information about secondary user store here
When authentication the users will be validated with all the existing user stores (primary and secondary). The possible issue will here is if the same username exists in two user stores.
If you provide user store name appended to the username, it will validate on the specific users.
For example, if the user store name is 'BPM', then you need to append as 'BPM/<username>'

AWS Cognito - create groups from ADFS as Cognito Groups

An app is communicating via the Open ID Connect protocol with AWS Cognito, which is connected to ADFS, communicating via SAML. Cognito is essentially "proxying" the ADFS server.
ADFS holds a group mapping that the app requires, and I would like to import these groups into Cognito as actual Cognito Group - which will then be read by the app from the cognito:groups from the ID-token Cognito provides.
In the AWS Cognito User Pool setup, I don't see a way to map ADFS groups to Cognito Groups - must I absolutely rely on a custom attribute for my User Pool that I can map to the ADFS-property, or am I missing some piece of configuration that allows Cognito to create new groups on the fly and automatically assign the users to the groups in Cognito?
edit: To clarify, Is it possible to setup Cognito to add/create groups (not as a custom property, but a actual manageable cognito groups) when it imports users?
I had the same issue, and I have not found a static mapping option in Cognito either.
The only way I see is to map the AD groups to custom:adgroups attribute in Cognito, and set up a Cognito "Pre Token Generation" lambda trigger. The lambda reads the value of the custom:adgroups and manually overrides the user's Cognito groups.
NB - this does not change the cognito user's group permanently, only for the current session, but from the application perspective that's exactly what I needed.
Please see a dummy static (non conditional) ADMIN group assignment example here:
def lambda_handler(event, context):
print(f'incoming event: {json.dumps(event)}')
# manual cognito group override
if event['triggerSource'] == "TokenGeneration_HostedAuth":
event['response'] = {
"claimsOverrideDetails": {
"groupOverrideDetails": {
"groupsToOverride": [
"ADMIN"
]
}
}
}
return event
More detailed documentation here: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
Could you use the Post authentication Lambda trigger to update the user's group in the Cognito User Pool based off the group in AD? You could use the APIs: AdminAddUserToGroup and AdminRemoveUserFromGroup. The only issue with this approach is that if you change the user's group in AD, it won't be updated in Cognito until the user authenticates to Cognito again.
How to setup ADFS with Cognito is documented in this link. The section answering your question is the mapping in step 4, item 5. I'm copying the relevant text below:
Choose Attribute mapping. These mappings map the claims from the SAML assertion from AD FS to the user pool attributes.
Make sure that ADFS is sending the groups in the assertions. For setting up the ADFS side for groups this link might be useful.
You could debug the flow with SAML-tracer plugin in Firefox.

Trigger Lambda function when creating new Cognito Identity

I want to use Cognito Federated Identities with multiple Authentication Providers, and I want to manage my own user database so I have a simple immutable unique user id for other areas of the application.
What would be the correct way to trigger a lambda function that inserts newly authenticated users into my user database?
If I was only using Cognito User Pools I could use the offered triggers, and would create a mapping of the User Pool's unique "sub" id to my applications user id, but if I use other Authentication Provider's (Facebook etc..) through Federated Identities there are no triggers offered.
I cannot see any triggers within Federated Identities.
I understand User Pools can now do federation within User Pools, meaning a Facebook sign up there would create a User Pool identity which would have a "sub" id I could use, but I feel the federation in User Pool's is not as mature and strong as in Federated Identities, there are also less Providers to choose from.
Secondary question: Is there a best standard for mapping Authentication Providers ids to my application user id? I understand sub is an immutable unique id for User Pools, but Federated Identitie's "Identity ID" can merge and thus change so I guess best practive would be to use each Authentication Provider's unique id?

AWS Cognito combined with other Rest apis except api gateway

Cognito is a powerful tool yet it's so hard to utilize it .
Trying to implement my business logic I ended up in some dead ends and I need some help.
My client app is an admin panel where a new admin can register providing a company.
Now there are 2 applications (Contests, Reviews) based on these companies .
So from the adminPanel the admin can create events for both apps through 2 different rest apis
The concept is 1 admin is related to 1 or more companies.I have to map that relationship somehow with Cognito .
Because cognito does pretty much well authentication but not authorization.
In every request not only I have to validate the user by the access token but I also have to see if the user is authorized to do the action based on the company.
For example if a user want to create a Contest event for his company.
I will make a request to Contest Api and I have to authorize that the admin is related to this company
Company entities are used from both apis so I have to expose them in a new api called companies.(If any api wants information about companies it should call the get company/{id})
My consideration is that in order to authorize a user in my apis I have to:
1) validate the access_token .
2) communicate with Cognito to get user informations.
3) call companies api to check if user is authorized to execute actions for this campaign.
So I kind of feeling that it becomes too complex and I need 2 services to authenticate and authorize each request(cognito + company api).
Is there any other way to implement cognito authorization logic without having to use a second api ?
P.S I have already check cognito triggers but they don't cover my needs .For example pre token generation trigger can add claims but it will add them in identity_token not access_token .Also my claims has to be an array of company_ids that an admin is related but claims supports strings and numbers only