define per user custom scope for cognito - amazon-cognito

How can I define custom scopes on a per user basis using cognito?
For example I have scope resource1.read, resource1.write
I want user A to have resource1.read and resource1.write while user B has resource1.read only.
This is just a high level example. We have tons of different resources and wants to allow customers to manage what resource each user has access to.
I havent found a way to associate scopes with each individual users but only at a per pool level.
Is there a way to achieve this using only cognito or cognito + some AWS manged service or do I have to implement another API to manage the scopes myself?

we couldn't find a way to make scope work on per user basis so we ended up using the custom attributes instead.
if you have less than 25 scopes (cognito max limit) then you can use one attribute per scope. P.S. just be aware you can't rename/remove the attribute once its in place unless you delete the whole pool and start over again.
For example your attributes might look like:
custom:resource1.read : "true"
custom:resource1.write : "false"
custom:resource2.read : "true"
custom:resource2.write : "true"
the idea is simple. instead of having all the scopes defined inside the scopes array we define it in regular custom attributes. When the code checks for scopes just loop thru all fields and find the one with correct prefix.

You could implement your own authorization service and call it with the Pre token generation Lambda trigger:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
This only applies to the ID token though, just like Steve's answer.
You can use this AWS Lambda trigger to customize an identity token before Amazon Cognito generates it. You can use this trigger to add new claims, update claims, or suppress claims in the identity token.

Related

Check if user existed in cognito as federated user by using only email/username

I'm having trouble implementing a feature where I need check if a user does not exist or is existing in cognito but as federated user. The prior is done without trouble but I'm stuck on the latter without any clue. I went through the cognito and amplify documents but couldn't find any clue. Could there be a work-around or a function that I don't know about, any suggest is welcomed.
You can create a mutable custom user attribute on Cognito such as isFederatedUser and set this on user during user creation.
If this is not possible, you can call list-users and filter the identities attribute.

Use WSO2IS to configure user access to entities

I'm trying to implement WSO2IS for authorization. My understanding is that in the WSO2 realm, the concept of a permission broadly restricts a user's access to an action, or a resource. So, for instance, if my app is a bookstore, I could configure whether a user has "read" access to authors at large, and toggle their access to the GetAuthors() endpoint. However, I need to configure a user's access to certain authors. Is there a way I can store a whitelist of authors on a per-user basis? What I'd like to accomplish is to have a user call a GetBooks() endpoint and return only the books written by the authors that the user can access.
It sounds like one possibility is to store this information in an external datastore, and implement a custom PIP to read from that datastore.
Another possible option would be to create a custom attribute on the User type and store the whitelist of author IDs in an array on each user.
Is there a better way to do this? I'd prefer not to implement a custom external datastore just to store relationships between users and entity ids. Is it possible to do this with XACML and policies? Is it possible to have WSO2IS stick this information on a claim that is returned to my controller so that I can limit my underlying query based on the user's whitelist of allowed entity IDs?
AFAIU you need to maintain a claim to track the accessibility for reading. You can easily create a custom claim to track it by following the article[1]. In this way, you can refer to the custom claim at the controller to make further decisions.
You have to update this claim value for each user. For this, you can use SCIM API[2] by following doc[3] to extend the SCIM endpoint for custom claims.
[1]https://medium.com/#inthiraj1994/lets-add-a-custom-claim-to-oidc-in-wso2-is-d871e418d6b0
[2]https://is.docs.wso2.com/en/latest/develop/scim2-rest-apis/#/scim-20-api-definition
[3]https://is.docs.wso2.com/en/latest/develop/extending-scim2-user-schemas/#extending-scim-20-user-schemas

AWS Amplify - update another user attributes

Is there a way I can update another user attributes using AWS amplify with cognito? I.e. when user reply to a post I want to change a rating of a person that started a thread. Or for this I will need a table in DB to manage it.
In docs i see that there is a method:
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#adminUpdateUserAttributes-property
but I dont see a way to use it in Amplify.
I have not seen any API of aws-amplify which can alter user attributes as admin.
Generally, it is good practice not to duplicate data or keeping data duplication minimal if unavoidable. In other words, keeping a single source of truth. Use Cognito as only for authentication, I mean obtaining JWT token.
Rating, user basic info, and role; keep those at your own data source.

How can i limit access to the aws-cognito service?

I would like to limit the access to my cognito service.
My scope is to filter all the calls to cognito adding a server layer that allow me to do specific actions when the user uses the service.
I know that triggering events is the right way to do this but the events in cognito are very limited and a lot of stuff can not be done. For example if the Authentication fails for some reason the postAuthentication event is not triggered.
Another use case can be the validation of the attribute, or limit the reading of some attribute.
The only idea I've is to hide the IdentityPoolId or the UserPoolClientId but seems pretty unsafe.
There are two approaches in using AWS Cognito UserPools.
Using Hosted UI.
Using the SDKs/RESTAPI and Implement Your Own API and UI interface.
Using Hosted UI
If you go with the first option, pretty much of the things are handled by AWS and the control you have is limited. However, you can do certain configuration using triggers. On the other hand, you have lesser risks from your side since you are maintaining a limited code.
Using the SDKs/RESTAPI
If you go with the second option, you can limit Cognito UserPools as required putting the logic inside your own code. This allows limiting access as you desire. However, you have to write custom code to authenticate and signup users.
Mix of Both
It is also possible to use a mix of these approaches. For example, you can write custom code for signup but for sign in use hosted UI.
Custom Attributes and Claims
Also if you plan to return attributes based on your custom rules, use the trigger Pre token generation. Amazon Cognito invokes this trigger before token generation allowing you to customize identity token claims.
Note: A similar approach can be done for the Cognito Identity Pools.

Danamic Claims in IdentityServer

I'm looking at the AspNetIdentity_2fa sample and trying to modify it to include some dynamic claims for users. Let's name it calculated_value claim which is created dynamically when a user is authenticated, and then is included in the user's claims list and passed with the the authentication token. I know I could create a separate Web API to get this value but since it is small data and that it is needed as soon as a user is authenticated, I thought I'd just pass it as claim. In the samples I see that claims always coming from static or hard-coded data. How can I create dynamic/late-bound claims?
Thanks!
Some time ago I spent some time on trying to integrate Identity Server v3 with Active Directory. I wanted to authenticate users via AD and to read "claims" from AD. To do so I provided a custom implementation of IUserService. It was more or less based on in memory implementation of these interface i.e. InMemoryUserService.
When your custom implementation is ready you have to register it. However, AspNetIdentity_2fa sample project already registers a custom implementation of IUserService i.e. UserService (just search a project for this class). It is derived from AspNetIdentityUserService which implements IUserService.
So, instead of providing completely new implementation try to modify it. I think that you should look at AuthenticateLocalAsync, AuthenticateExternalAsync and GetProfileDataAsync methods (see InMemoryUserService for reference) and override them. First 2 are used to authenticate users and the last one to read requested claims for users.