Iam authentication with r2dbc-postgresql - amazon-iam

For working with IAM authentication for a DB, a dynamic password is required to refresh the connection pool with new credentials. in r2dbc-postgresql I could not find any possibility of a custom datasource like the one in HikariCP. Also there is no option to supply a dynamic password as concrete final class is used for config (PostgresConnectionConfiguration)
Any hints for a workaround?

Related

Cognito authentication with username or unique email via AWS Amplify

Amplify CLI authentication with Cognito user pools currently has two main modes, signin with username or with email. In the former case email uniqueness as a required user attribute is not being enforced.
Cognito service by itself supports the "Also allow sign in with verified email address" option (AWS Console, User Pool Attributes-section) but it can be set only upon user pool creation (i.e. can not be modified later - checkboxes are disabled). Is it possible to enforce no duplicate emails within the user pool while allowing users to authenticate with username or with email?
To summarize, my use case requires:
Verifying/enforcing email attribute uniqueness at the Cognito level when signing up users via Amplify's Auth.SignUp;
Keeping username-based login but allowing users to login with their email as well (that is, Auth.SignIn with email or username supplied as the username-argument).
When you add the user pool with amplify add auth choose 'Username' as the method with which you want users to sign in when prompted.
If you aren't prompted with this choice, you might need to try amplify add auth again but this time choose Manual configuration when prompted at the beginning.
Once you've completed the entire auth set up via amplify add auth, BEFORE you run amplify push for the first time, run amplify override auth.
This creates a new override.ts file which you can edit with AWS CDK code to customise your Cognito resources beyond the abilities the CLI allows.
You can find the override.ts file at:
amplify\backend\auth\<your_app_name>\override.ts
Inside the override file, add the following line into the empty function that's made for you:
resources.userPool.aliasAttributes = ['email'];
Now you can save the file, and run amplify push and hopefully your new user pool will show in the AWS Console that you've successfully configured it to allow user name and email sign in together.
You have to make sure you write the override code before amplify push or your user pool will be created in the cloud, and attempting to override this sign in functionality after the user pool has been created throws an error as it's read only.
If you find yourself in that position, you'll need to create a new user pool, you can't modify the existing one.

How to debug Cognito's idpresponse endpoint

I'm setting up OIDC provider for Cognito User pool. The open id connect service I'm using is Paypal. At the step where paypal issues code and redirects to cognito's /oauth2/idpresponse endpoint after which cognito is supposed to exchange the code for access token, I'm receiving "Exception processing authorization code" error. As you can see the error message is not very discriptive.
I have no idea what I'm doing wrong. I did setup open id connect properly. Setup client settings in cognito and etc.
These are the endpoints I'm using for openid connect:
https://www.sandbox.paypal.com/signin/authorize
https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice
https://api.sandbox.paypal.com/v1/oauth2/token/userinfo
https://api.sandbox.paypal.com/v1/oauth2/certs
In app client settings I have auth code grant flow and implicit flow enabled. I have custom domain setup. I provided paypal client id and secret
My guess is if I'm able to somehow debug idpresponse endpoint I should be able to solve the problem. Is there any way to do that? Maybe cloudwatch?
I don't know about debugging Cognito's endpoints, but I had the same problem and fixed it by doing the following:
Go to your User Pool in AWS.
In the side navigation under Federation, select Attribute mapping.
Click the tab of the identity provider you're having issues with (in my case it was Google).
There should be three columns, Capture, Google attribute, and User pool attribute. Make sure all of the attributes that are checked in the Capture column are mapped to an attribute in the User pool attribute column.
UPDATE:
After submitting this answer, I realized that the checkboxes in the Capture column are not checked by default. If you marked any attributes as required in the Attributes section of your user pool, then you need to map those attributes to the attributes provided by your external identity providers.
For example, I marked email as a required attribute in my user pool settings. So, when I added Google as an identity provider, I had to go to Federation->Attribute mapping, click on the tab for Google, check the box in the Capture column next to email, and select Email from the dropdown box in the User pool attribute column.
After taking these steps, the sign in work-flow worked for me.
My guess is the auth flow works just fine between Cognito and your identity provider, but Cognito doesn't know how to map the attributes returned from the identity provider to the attributes you have set in your user pool (in General settings->Attributes under the Which standard attributes are required section).

Cognito User Pools - Is it possible to create a custom sign up/in form for Facebook login?

I would like to use a Cognito User Pool for Facebook logins only, which may be possible using the built in login form, but I need to use my own.
Theoretically, when it comes to a custom form, it shouldn't be hard: after I receive a user object from FB, I bind the user and email attributes to the ones in my User Pool and I save it.
But what to do about the password field and future authentication? And here I have failed during my journey...
...
userPool.signUp('FoobarUser', '**password?**', attributeList, null, function(err, result){
...
While digging deeper into the docs, I tried to implement a Identity Pool (Federated Identities), managed to save user info in the form of datasets as well, but then I realised, querying these sets gonna be a huge pain if possible at all.
Maybe I'm failing to understand the concepts, I would be really thankful if someone could suggest a way to manage facebook logins in a nicely organised fashion using Cognito.
So here is what I understand from your query.
Setup
Link Facebook to userpool
The app client allows only Facebook login, no other providers allowed (not even Userpool)
On login, you want Facebook user's info to be automatically populated in your Userpool
You don't want to use Cognito's builtin UI but use your own
My 2 Cents
In your app client, just select Facebook
In your UI, have a login button. On clicking it should redirect to your userpool's authorization endpoint
https://your_domain.auth.us-east-1.amazoncognito.com/oauth2/authorize?redirect_uri=https://www.example.com&response_type=token&client_id=your_appclient_id
If you want to use your own UI with multiple providers, allow the same in Client and on clicking the appropriate button in your UI (say Facebook), redirect users to the authorize endpoint but append the identity_provider in the URL
https://your_domain.auth.us-east-1.amazoncognito.com/oauth2/authorize?redirect_uri=https://www.example.com&response_type=token&client_id=your_appclient_id&identity_provider=Facebook
If you want to see the names of all supported identity providers, use ListIdentityProviders API call
This way, all Facebook users will be automatically created in your userpool. Of course, their names will be random like Facebook_123jkjdwj but all their details will be correctly populated from the token as per your attribute mapping. As a plus, all auto-created users from a particular provider are added to an auto-created group 'Userpoolid_providername' eg. us_east_1_xxxx_Facebook.

initialize amazon aws cognito client via BasicAWSCredentials vs CognitoAWSCredentials

What is the difference between these two approaches of initializing a new AmazonCognitoIdentityClient?
AmazonCognitoIdentity identityClient = new AmazonCognitoIdentityClient(
new BasicAWSCredentials("access_key_id", "secret_access_key")
);
identityClient.GetOpenIdTokenForDeveloperIdentity()
-
AmazonCognitoIdentity identityClient = new AmazonCognitoIdentityClient(
new CognitoAWSCredentials ("IDENTITY_POOL_ID", "REGION_NAME");
);
identityClient.GetOpenIdTokenForDeveloperIdentity()
Although most examples on the internet show BasicAWSCredentials being used to instantiate a CognitoIdentityClient, but the method signature in the doc says it accepts AWSCredentials class - both BasicAWSCredentials as well as CognitoAWSCredentials are subclasses of the AWSCredentials class. Hence, i am assuming both should be working normally i guess???
I am trying to understand how will this difference, impact the following:
privileges,
timeouts,
etc?
API reference for cognitoIdentityClient constructors is here: http://docs.aws.amazon.com/sdkfornet/v3/apidocs/index.html?page=CognitoIdentity/TCognitoIdentityCognitoIdentityClient.html&tocid=Amazon_CognitoIdentity_AmazonCognitoIdentityClient
In client device you should instantiate AmazonCognitoIdentityClient client using CognitoAWSCredentials. Using STS service, AWS client will obtain temporary credentials that will let the client assume the role you previously defined in your identity pool. Typically this role would have very limited access to your AWS resources. (S3 upload to a specific bucket etc.) This is like giving out to people a special type of your car key which can only turn on the music system, not the engine.
On the other hand GetOpenIdTokenForDeveloperIdentity is a special API call that needs developer credentials. You should never deploy developer credentials to any client device and you should keep it only on your server. Once you instantiate a AmazonCognitoIdentityClient using developer credentials on your server, you can expose a REST endpoint for clients to obtain OpenId token (for a given identity id or creating a new one). Let's assume that your users are logging in to your API using their username and password and you return them a custom access token which is stored in your database. After that your endpoint may implement this logic:
Fetch unique identifier for your user using custom token (user id, username, e-mail etc.)
Use LookupDeveloperIdentity and find out the identityId for the given username.
Use GetOpenIdTokenForDeveloperIdentity with found identityId and send back to the client. So they can "login" to that identityId.
If this user has not any identityId assigned to its username, create a new one and send back.
As you see developer AWS tokens are enabling a couple of sensitive API calls. Now let us assume that client had developer access token and thus has access to GetOpenIdTokenForDeveloperIdentity call. Then they would be able to generate OpenId tokens, switch to other people's identities easily and access their private data.
If you don't use developer authenticated identities (https://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html) you do not need GetOpenIdTokenForDeveloperIdentity mechanism though. If you are using only public authentication methods (Twitter, Facebook etc.) you should ignore the second paragraph and use CognitoAWSCredentials.
As described in Çağatay's answer, the BasicAwsCredentials are instantiated with your developer credentials. What he described about when to use each constructor is absolutely correct in every case other than developer authenticated identities.
Since this code will be deployed on a back end service, it's exposure is less of a concern. Mobile clients will communicate with this server and get the token from it, with which they will get credentials. The credentials are never exposed to the user in this pattern.
As you can see in the Cognito documentation, the sample has BasicAwsCredentials. An end to end sample is visible in this blog post.

Centralized auth in service oriented architecture

I'm exploring basic service oriented architecture and I'm wondering how to best handle user authentication throughout the services.
As a very simple example, suppose we have a blog app that calls out to two other services:
A user/auth service for storing user data and exchanging credentials for an access token
A posts service for managing post data
Let's say a user of the application is attempting to delete a particular post and that only users with an "admin" role are allowed to do so.
The following requests would need to be made:
app -> auth
Authenticate the current user (via some sort of token). If the token is expired the app could redirect the user to a login form, etc.
app -> posts
Delete the post.
posts -> auth
Before a post is deleted, the post service needs to make sure the requesting user has permission to do so. Authenticate the current user (via token) and make sure they have the "admin" role.
This is an overly simple example but I'm curious how folks are dealing with auth throughout their services. It seems likely that each service would need to make a separate call to the authentication service in order to authorize the request. Is this the case? Are there better ways to handle auth in this kind of SOA?
Thanks!
You can implement an identity provider - Once a user authenticates with the authorization/authentication service she should get a token that identifies her. This token can identify her (roles/claims) and signed by the authentication/authorization service private key. When a service gets a security token and it is signed by a trusted authority it doesn't need to go to the authentication/authorization service again.
If your system has a higher security requirements (e.g. at the user level) you may need either elaborate claims or to access the authorization system on each request. I worked once on a system where certain types of info required authorization on every access and other types were ok with role based security - your millage may vary.