AWS Cognito with external IDP (SAML) for Post-Signup/Signin Actions - single-sign-on

I also need to add the created/updated user into a users-table of an RDS-database, and the described workflow does not describe such a scenario at all.
Is it possible to react to the create/update of a cognito user within this SAML-workflow, by also updating an applications database-table with the new data?
--
In the docs of AWS Cognito in the Chapter "SAML user pool IdP authentication flow" there is following part written:
6. After verifying the SAML assertion and collecting the user attributes (claims) from the assertion,
Amazon Cognito internally creates or updates the user's profile in the user pool.
Amazon Cognito returns OIDC tokens to the app for the now signed-in user.
see: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-saml-idp-authentication.html
this part does not seem to recognize the scenario i described in my question, and there is no link/hint to such a solution given.

In order to perform additional actions to customize the Cognito user pool workflow, you can use Lambda triggers.
In your particular situation, there are triggers and triggerSource values you should look for regarding Sign Up and Sign In for federated users, as per documentation, namely:
For SignUp:
PreSignUp_ExternalProvider this is called before the user is created in Cognito, allowing to perform some additional actions, normally validations.
PostConfirmation_ConfirmSignUp is invoked after the user has been created and confirmed in Cognito. This would be where you'd create it at the RDS Database.
For SignIn:
PreAuthentication_Authentication similarly to PreSignUp, useful for additional validations, but for Sign In.
PostAuthentication_Authentication called after a successful authentication. This is where you would update the User at your Database.
Also keep in mind that the Updated date of the user will change at each new sign-in due to this (source) :
Amazon Cognito must be able to update your mapped user pool attributes when users sign in to your application. When a user signs in through an IdP, Amazon Cognito updates the mapped attributes with the latest information from the IdP. Amazon Cognito updates each mapped attribute, even if its current value already matches the latest information.

Related

Verify if a user is deleted or not using SAML token

I have an application that I integrated SSO using Azure AD identify provider. There is an option in Azure AD to delete user. So, the requirement is to sign out from my website when user is deleted in Azure AD. We store SAML token when user is successfully authenticated. Is there any way to check if user is exists or not using SAML token?.
Unfortunately, this is not possible by using SAML Token as of now.
Microsoft recently introduced Continuous Access Evaluation (CAE) for this purpose but the initial implementation of it focuses on Exchange, Teams, and SharePoint Online.
Continuous access evaluation enable services to subscribe to critical events in Azure AD so that those events can be evaluated and enforced near real time. Some examples of these events are:
User Account is deleted or disabled
Password for a user is changed or reset
Multi-factor authentication is enabled for the user
Administrator explicitly revokes all refresh tokens for a user
High user risk detected by Azure AD Identity Protection

Flask-OIDC | How to call a specific function after the user logged in

I built a login system using Flask OIDC and Keycloak. In my system, there is some endpoints decorated with oidc.require_login() that calls the Keycloak login page.
My goal is, after the user successfully logged in, my system checks if the user name exists in a specific database.
How can I set a function to be called every time someone successfully logged in with Keycloak and do this verification at the database?
According to your needs there are several ways to create the user in the backend.
The easiest way would be to just check the JWT token on every request. OIDC is based on JWT and that token is available on any request (which should already be done to find user roles etc). So your application can check that JWT and extract the username from it (see here for details about the JWT format). With the username you can check your internal database and create the user, if it doesnt exist. But at that time you'll not have access to any user credentials any more. It is just SSO and you need to trust Keycloak and the JWT... Also - you'll never be informed, if the user will be deleted in Keycloak, which could be an issue.
There is a callback API in Keycloak in form of the Admin URL per client. But the documentation is not clear. It says: It’s used by the Keycloak server to send backend requests to the application for various tasks, like logout users or push revocation policies. But I cannot find a complete list of "tasks". I saw only logout events. see Keycloak documentation and the documentation only talks about that. If I add an admin url to a test client, I did not get any requests at login time.
a different but more complicated way would be to create your own UserStorage SPI in Keycloak. It would be Java of course, but only some classes. There is an HTTP example or have a look at the LDAP user storage SPI, which supports registration too. If you choose that for your realm and a user tries to login to Keycloak (Login form), the SPI can call your backend to check the user. It also could be "used" to create the user in the backend by checking the Keycloak local storage and only if there is a local Keycloak user, call the backend. That isn't the reason, why you should implement the UserStorage SPI, but it's possible. If you think, this is a good idea, I would prefer to use your backend storage as the one and only storage or build a different one, that then could call your real backend in case of a new user. I would use this one by not using Keycloak local stored users but, by using your own database.
next (maybe last one). You can write an EventListener SPI to read all events and only filter the login events, see here and here. I think, that would be the easiest one. But be aware. In that case, the HTTP call to your backend coming from the event itself is based on a normal HTTP request (without OIDC at that time).
The last two examples create a JAR (which is explained in the links). That JAR with the SPI must be deployed in keycloaks standalone/deployments folder. The EventListener should be active by default, the UserStorage SPI must be activated per realm.
But - be aware - Keycloak/SSO/JWT - should not be used by creating users in multiple backends. Syncing the users between all backends in a SSO environment is maybe the wrong way. Most information is located in the JWT or can be called by a backend from one central user identity management. Do not store a user more then once. If you need the user reference in your backend - link just to the username or userid (string) instead of a complete entity.
There is no direct way of doing this, other sotfware like Openam, Okta allow you to trigger specific flows in a post-login configuration.
In keycloak, you can try to create your custom authn flow(using Default Identity Provider, its the only option that allow a redirect), and then select this flow in your Identity provider in post login flow.
The idea here is that after login, the user will be redirected to a link ( an api call that will verify his presence on the external database, and sent him back to keycloak once the verification is done.
More info here

Create my own AccessTokens with MS Identity Platform

I am in the process of expanding our login options on our product to support MS Identity Platform, to be able to use Azure AD login (and gain SSO/MFA with that)
Currently we are using .Net Core + JWT (JwtBearerDefaults.AuthenticationScheme)
The environment is angular clients, .Net Core APA, and a back-end database.
I have the setup working.
My challenge is that in our business model and backend database we have ~2.000 userrights and our own User/Role model granting access.
I am currently getting the IdToken from MSAL and in my proof of concept using the oid to couple the Azure ID with our User model.
But, in our existing JWT solution, our access token holds claims about the User Id, but also the role, and another property (Unit/Vessel) determining access. From these three properties we can verify against the 2.000 userights on API side whether or not a request is allowed or not.
I would like to keep this information (User, Role, Unit) in the token - but have doubts on how.
Constraints:
We cant create/use Azure claims. We have too many, and customers will manage the Azure application - while we create, add, remove rights for each version of our software.
Azure don't know about role/unit data - and these are different for each customer - so that information can't be in Azure either.
My best idea is outlined below - would this approach be correct, and live up to the way ID/Access is separated?
I hope someone can give me some feedback on this.
My idea is, that the Angular client gets the Azure IDToken. I then use the Azure IDToken, call our API, which on server side, validates ID Token, and then grants me an access token, which contains the user, role and unit. This token is not Azure'd at all, just a token generated by our API - which again will be the only one validating it). Pro's on this approach is also I can keep one type of Access Token, no matter which IDToken is supplied by Azure or our own API.
Tried to outline the flow below in this DrawIO diagram.
I hope someone with more experience in the Token field can validate if this would be a viable approach?
Best regards
/Anders
This is a viable approach except for one thing.
Do not use Id token for authorization.
Your front-end should acquire an access token from AAD for your back-end.
This access token contains the user objectId, allowing you to map the user to a user in your database.
An Id token is only meant for the application that requested authentication and tells it metadata on the user like their display name etc., but it is not meant for authorizing anything.

Is there a way to authorize users with existing account only?

Iam working on a flutter mobile application where i use Google SignIn for Auth, is there a way to authorize users with existing account only?
Prevent users from creating new accounts? I've looked for the same thing without finding a way to do this with any Firebase project setting.
The solution, I believe, is consider the difference between authentication and authorization. Firebase's Authentication service is aptly named. It does authentication
- validates that a user is actually who they claim to be. It does not do authorization - control what actions authenticated users are allowed to perform or what data they can access within an application. App developers have to be responsible for managing user authorization.
One way to do this is to maintain a collection of "authorized users" in Firestore, for example. When a user authenticates, your app would perform a lookup to see if the current user is actually authorized or not. Security rules can be written for Firestore and Firebase Cloud Storage to also validate that the current user is in the "authorized users" collection before allowing access to data. But this requires extra data queries to obtain this authorization info.
The authorization method I prefer is to use Custom Claims which can be assigned using the Firebase Admin library. A custom claim can be added to an existing user account that can act as a flag indicating what type of authorization they're granted. Front-end code can check the authentication token they've been issued for the custom claim to determine the authorization they've been granted. Server-side code and security rules can also check for those required custom claims within submitted requests.
Realistically, any application you build where different users might have different levels of access will require you to deal with authorization. I believe that assigning carefully thought-out custom claims is the best solution.

Amazon Cognito authenticate user with saml and get table data from DynamoDB. Swift

I am new to Amazon Web Services.
All tables are stored in DynamoDB. My query is how to manage and authenticate user ?
For Example.
Suppose assume I have username called mike and password is testmike. When I press login button using cognito (SAML) they autenticate user and if user return success message then fetch all table data from that user pool. How can we achieve this? I already read amazon developer guide I am confused How to implement in my code.
Or without SAML is this possible ?
Can anybody provide sample code here ?
Your help is really appreciated .
If you have your own user directory which supports SAML IdP then you can use SAML federation and access your DynamoDB table with Cognito identity credentials.
If you want to create user signup and signin functionality and let Cognito manage your users, you can use Cognito user pools. User data is not stored automatically in DynamoDB. If you want to store some additional data related to user, you can federate Cognito user with Cognito identity and use these credentials to write to Cognito sync or DyanamoDB.