How and what should i pass in order to get value for { cognito-identity.amazonaws.com:aud } to IAM role? - amazon-cognito

What I have done so far is-
I have signed in user with Cognito identity, in return i get a 'session token' which contains 'aud' inside it. But while I pass token through headers, it's not recognizing. Its send back error,
message: 'User: arn:aws:sts::4954355577:assumed-role/multi-test-application-dev-us-east-1-lambdaRole/multi-test-application-dev-list is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:4954355577:table/tenantTable',
Or Is this a wrong way? So if its wrong, What and How should I pass the data in order to get aud inside the IAM role for ${cognito-identity.amazonaws.com:aud}?

We cannot pass the aud as a global variable or an env variable. Once we get the credentials from an identity pool, which is the secret token, access key id, and session token. We need to create dynamodb instance using these credentials. So whenever we use dynamodb, the aud will be set as identity pool id.

Related

IAM role for multi-tenancy (Identity platform)

I am currently working on multi-tenancy using admin auth as per the documentation: https://cloud.google.com/identity-platform/docs/multi-tenancy
I initialized a Tenant Auth with a registered tenantId:
const tenantManager = admin.auth().tenantManager();
const tenantAuth = tenantManager.authForTenant(tenantId);
let tenantData = await tenantManger.getTenant(tenantId)
When I perform any operations using this tenantAuth or get the tenant data, I get the following error
An internal error has occurred. Raw server response: "{"error":{"code":403,"message":"The caller does not have permission","status":"PERMISSION_DENIED"}}"
I can understand it is an IAM role required for the service account key I used for initializing the admin SDK. Can anyone tell what's the valid role to be added?

Agora.io security token generated invalid (Golang)

Having problem getting security token generated from my server to work properly. I modified the basicLive.js of the demo in AgoraWebSDK-NG to work with my server. I'm using the Golang api provided by Agora to generate the token. Some information:
AppID: ---
App Certificate: ---
channel name: liveshow10
uid: 51495 (I assume Agora does not care about this as long as it is uint32)
token expiration seconds: 3600
generated token: 006cb08a5a2ddc049f79f29d9b52e5909b0IABKKxbI64sFWnkyEICQrL+0DeTsrN9ckKMkDj/oir36aV+tq536WyGcIgCHHmUFHNv6XgQAAQCsl/leAgCsl/leAwCsl/leBACsl/le
But I'm getting bunch of error in the console. I think it boils down to an authorization error the token generated somehow is invalid. Below is the browser console and thanks for any help:
For anyone following along, the issue was related to UID. In the above code the token is generate specifically for UID 51495 but in the Agora Demo, the JoinChannel method passes null as the UID value which tells the SDK to generate its own UID for that user.
When attempting to join a channel with a different UID than the one used to generate the token, you will receive an error.
If you want to generate a token that can be used by any user, you need to set the UID to 0 in the token generation, and then you can use any UID join the channel with this token.
Update: The UID 0 detail can be found in the Token Server API reference within the UID parameter description docs.agora.io/en/video/token_server#api-reference

Express REST API with JWT and Routes

I am trying to create an Express API with JWT authentication.
However, I was wondering how to best allow users to only access their own resources.
For example if there is a user with id 1 and each user has a list of books in the database:
The id is already part of the JWT Token but commonly there would be a request to something like /users/1/books to get all of the books belonging to user 1.
Would my routes typically still look like this and I would just check the id in the token is the same the request is made for, or is there any other/simpler way?
Thank you for your help!
You can define, some access rights permissions base on the user role or id.
Example: roles : {root, admin, staff}
Then, in your routes you can have some checking whether this user have the permission to access the functions or you can do in the controller level to check the access rights.
You need to define model relations between User, UserModel. In your case as I understand you need to have the relations between UserModel and BooksModels.
UserModel hasMany BooksModel
When you call findOne() to retrieve specific user's data, you can just define include: 'aliasModelName', to retrieve the users related book data.
With this way, you can only have 1endpoint users/:id to retrieve users data and book data. It depends on what you really want, you can also have an endpoint users/:id/books to get all books that belongs to this user.
Your model definition will then become
BooksModel belongsTo UserModel
If you use hasMany you can get all the results that you need in just one query.
Hope this helps!
When user sends the login credentials, you check database if the email exists, if yes then you check if the password matches. If user successfully signins you create the token.
const token = jwt.sign({ _id: user._id, email: user.email }, "this-is-secret", {
expiresIn: "1h",
});
this token is sent to the browser, whenever user make requests, it manually attachs this token to the req, and sends the request to your server. You check if the token is valid, by using the secret key (in this case "this-is-secret").
const decodedToken = jwt.verify(token, "this-is-secret")
req.userId = decodedToken.userId;
now "userId" is attached to the req object. Now when you fetch the data from database, the items that you are fetching, you write a query that (implementation depends on which database you are using)
book.userId=req.userId

How can i get userId of aws account?

I am using a API call to retrieve the plaintext instance identity document. Here, accountId is present.
response = response.get("http://169.254.169.254/latest/dynamic/instance-identity/document").text
I am using the above code in my python script. How can i get AWS userId by API call?
Not sure if this is what you are after, but get_caller_identity returns UserId and Accountid:
UserId (string) The unique identifier of the calling entity. The exact value depends on the type of entity that is making the call. The
values returned are those listed in the aws:userid column in the
Principal table found on the Policy Variables reference page in the
IAM User Guide .
Account (string) The AWS account ID number of the account that owns or contains the calling entity.
Arn (string) The AWS ARN associated with the calling entity.
Example output is (from docs):
'Account': '123456789012',
'Arn': 'arn:aws:iam::123456789012:user/Alice',
'UserId': 'AKIAI44QH8DHBEXAMPLE'

Get new access token with Authorization Code OAuth2 - Using Robot framework

I have some troubles with getting Access token with grant type authorization code using Robot framework with Oauth2.
We use also a username/password authentication and after give the following parameters we get back our access token:
Grant Type, Callback URL, Auth URL, Access Token URL, Client ID, Client Secret, Scope, State.
I tried with RequestsLibrary and ExtendedRequestsLibrary as well, but no success so far.
Actually I do not know how to add parameters: callback url, auth url, access token url and state.
First try - using RequestsLibrary
Get admin token
&{HEADER_TOKEN}= Create Dictionary Content-Type=${CONTENT_TYPE}
&{DATA_TOKEN}= Create Dictionary token_name=backend_token grant_type=${GRANT_TYPE} redirect_uri =${CALLBACK_URL} auth_url=${AUTH_URL} access_token_url=${ACCESS_TOKEN_URL} client_id=${CLIENT_ID} client_secret=${CLIENT_SECRET} scope=${SCOPE} state=${STATE} username=${USERNAME} ${PASSWORD}
${BACKEND_RESPONSE}= RequestsLibrary.Post Request ${BACKEND_SESSION} /oauth/token data=${DATA_TOKEN} headers=${HEADER_TOKEN}
Log to console ${BACKEND_RESPONSE}
Should Be Equal As Strings ${BACKEND_RESPONSE.status_code} 200
Second try - using ExtendedRequestsLibrary
Get brand new admin token
${SESSION_RESPONSE}= Create Password Oauth2 Session client ${TOKEN_URL} ${CLIENT_ID} ${CLIENT_SECRET} ${USERNAME} ${PASSWORD} base_url=${BASE_URL}
&{HEADER_TOKEN}= Create Dictionary Content-Type=${CONTENT_TYPE}
&{DATA_TOKEN}= Create Dictionary token_name=client grant_type=${GRANT_TYPE} callback_url=${CALLBACK_URL} auth_url=${AUTH_URL} access_token_url=${ACCESS_TOKEN_URL} client_id=${CLIENT_ID} client_secret=${CLIENT_SECRET} scope=${SCOPE} state=${STATE}
${BACKEND_RESPONSE}= ExtendedRequestsLibrary.Post Request client /oauth/token data=${DATA_TOKEN} headers=${HEADER_TOKEN}
Log to console ${BACKEND_RESPONSE}
Should Be Equal As Strings ${BACKEND_RESPONSE.status_code} 200
Log to console ${BACKEND_RESPONSE.status_code}
If you have any idea just let me know.
thx!
using RequestsLibrary try with this approach it should work:-
Create Session baseUri https://xxxxxx.xx.xxx/xxx/xx verify=True
&{params}= Create Dictionary client_id=${client_id} client_secret=${client_secret} grant_type=${grant_type}
&{headers}= Create Dictionary Content-Type=application/json
${resp}= Post Request baseUri /oauth/token none none ${params} ${headers}
Log to Console ${resp.json()['access_token']}
Status Should Be 200 ${resp}
you are passing data=${DATA_TOKEN} as a body in your post request. You need to send it as query params. First parameter will be alias 2nd is uri 3rd is data 4th is Json and 5th is query params so in
Post Request baseUri /oauth/token none none ${params} ${headers}
you will find 3rd and 4th parameter as none. Hope this works