Api created with Chalice and a Cognito authorizer returns “Unauthorized” - aws-api-gateway

I'm trying to integrate Cognito using the built-in login dialog with AWS Chalice. This is what I tried:
# This passes in correct arn for my pool, not xxxx
authorizer = CognitoUserPoolAuthorizer(
'end_users_dev', provider_arns=['arn:aws:cognito-idp:us-west-2:xxxx])
#app.route('/test', cors=True, authorizer=authorizer)
def test():
return {"result": "Success with authorizer"}
#app.route('/test2', cors=True)
def test2():
return {"result": "Success without authorizer"}
The second method (test2) works but the first method (test) returns (as expected):
{
"message": "Unauthorized"
}
Now I attempt to make the test with authorization work by passing in a header:
Authorization: <the token I get passed in from the
built in login page callback as "id_token">
I can verify the JWT token contents and signature manually and that the user pool is showing up in API Gateway as "Authorization" for the test resource, but I'm still getting the same "Unauthorized" message. What am I missing?
(Note: I also posted this at https://forums.aws.amazon.com/message.jspa?messageID=871715#871715 but haven't received any response in 2 days)

I would check to make sure your IAM policy chalice is running allows access to cognito.
You can add these as needed from the AmazonCognitoPowerUser policy to your policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-identity:*",
"cognito-idp:*",
"cognito-sync:*",
"iam:ListRoles",
"iam:ListOpenIdConnectProviders",
"sns:ListPlatformApplications"
],
"Resource": "*"
}
]
}
As see at the link below "
Whenever your application is deployed using chalice, the auto generated policy is written to disk at /.chalice/policy.json. When you run the chalice deploy command, you can also specify the --no-autogen-policy option. Doing so will result in the chalice CLI loading the /.chalice/policy.json file and using that file as the policy for the IAM role. You can manually edit this file and specify --no-autogen-policy if you'd like to have full control over what IAM policy to associate with the IAM role.
"
As seen under the policy section here: https://github.com/aws/chalice
$ chalice gen-policy
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"*"
],
"Effect": "Allow",
"Sid": "9155de6ad1d74e4c8b1448255770e60c"
}
]
}

Related

clientId missing from resource_access field in jwt token when using impersonation

I'm using Keycloak 14.0.0 and enabled the feature preview of token_exchange in order to do impersonation. After configuring my user in Keycloak to take on the impersonation role on the client "realm-management" (as according to the [documentation][1]), the actual request to do the token exchange fails as the token is not valid.
After some debugging it turns out that the jwt token is indeed malformed:
...
"session_state": "a03aeg0e-b5ce-4a50-9038-c339e50338c4",
"acr": "1",
"allowed-origins": [
"http://0.0.0.0:9180"
],
"scope": "openid identity_provider email admin profile company",
"permissions": [
"consented-readonly",
"readonly",
"trackingdisabled"
],
"resource_access": {
".roles": [
"impersonation"
]
},
"email_verified": false,
"idp": "myidp",
...
In the above, please notice the ".roles". I assume this is incorrect. It should be something like:
"resource_access": {
"myclient": {
"roles": [
"impersonation"
]
}
How can this be fixed?
[1]: https://www.keycloak.org/docs/latest/securing_apps/index.html#impersonation
It turns out that the configuration of a mapper was incorrect. In this case it was the "client roles" mapper (client scopes -> roles -> mapper -> client roles in keycloak ui) which, in my keycloak setup, had the value of:
resource_access..roles
This is incorrect as it should contain a clientId placeholder as shown below:
resource_access.${client_id}.roles
after this change the accessToken includes the actual client resulting in a valid json in the accessToken

Keycloak: 404 creating a role mapping for a user

I'm trying to use Keycloak's admin API in order to add a client-level role to the user role mapping. For this purpose I'm using the admin endpoint :
POST /{realm}/groups/{id}/role-mappings/clients/{client}
e.g.:
http://localhost/tests/admin/realms/testrealm/users/d1a15b4c-9853-4d87-9b8d-d4cf3fac3650/role-mappings/clients/3f222762-5300-48f2-be48-32f001d5a7dc
Request body as:
[
{
"id": "32f02358-9312-4b7b-8584-85dcaf257667",
"name": "test_role_app",
"description": null,
"scopeParamRequired": false
}
]
The id in the body request, is the role ID.
Keycloak is responding with error 404 with message:
{
"error": "Role not found"
}
Not sure what is the problem here as the role exists in the system. What could be wrong here?
Turned out to be that I was using the wrong roleId. I had two roles with same name (one at realm level and another one at client level). After using the correct ID everything worked well!
Additionally the whole request body looks like:
[
{
"id": "94cf6502-0375-4b62-a3ae-465d047738c3",
"name": "test_role_app",
"composite": false,
"clientRole": true,
"containerId": "a7e640cb-751d-4caa-81a0-79d38d31e025"
}
]

Keycloak RestAPI: Assign client role to group

I have trying this:
url="https://{localhost}/auth/admin/realms/{realm_name}/groups/{group_id}/role-mappings"
payload=[{"id":"role_id","name":"Role_name","composite":"false","clientRole":"true","containerId":"client_id"}]
But, it doesnt work, i think it may be related to the wrong payload
Any ideas pls
We can use the python-keycloak lib: https://pypi.org/project/python-keycloak/
there is a function: assign_group_client_roles
The format is correct but you make sure the client has available payloaded role.
This is example for, "Hr" group added "RomoteApp" client the "tile limit" role.
In Keycloak UI, # Client > RemoteApp > Roles
Role name
time limit
Groups > hr
Client Roles: RemoteApp
Available Roles: time limit
Assigned Roles: not yet include "time limit"
POST commend by Postman - I am not yet can attache image due to low level of stan overflow
http://127.0.0.1:8080/auth/admin/realms/Test-realm/groups/9efef6bf-7edb-496e-bc0d-a8d4f5f4e3a9/role-mappings/clients/60a19179-f244-42f8-9950-04f2119a4e5b?client=RemoteApp&id=60a19179-f244-42f8-9950-04f2119a4e5b&realm=Test-realm
in body of postman with row JSON option ( Content-Type : application/json )
[
{
"id": "e17f9f7f-62dc-4998-b058-49b845ff5cef",
"name": "time limit",
"description": "time limit",
"composite": false,
"clientRole": true,
"containerId": "60a19179-f244-42f8-9950-04f2119a4e5b"
}
]
group list
{
"id": "9efef6bf-7edb-496e-bc0d-a8d4f5f4e3a9",
"name": "hr",
"path": "/hr",
"subGroups": []
}
client list
{
"id": "60a19179-f244-42f8-9950-04f2119a4e5b",
"clientId": "RemoteApp",
...
}
also don't remember the access token called by token endpoint w/ grant_type is password
http://127.0.0.1:8080/auth/realms/Test-realm/protocol/openid-connect/token

Not able to create user using keycloak api

Getting token is successful:
Post: http://localhost:8180/auth/realms/public-library/protocol/openid-connect/token
Content type:application/x-www-form-urlencoded
Body:x-www-form-urlencoded
client_id:spring-boot-app
username:pooja.kumawat
password:poojakumawat#23
grant_type:password
Output:Token
Creating a user is getting an error:
Post : http://localhost:8180/auth/public-library/users
Authorization:Bearer+Token
Content type:Application/Json
Body:Raw
{
"username": "name",
"enabled": true,
"emailVerified": false,
"firstName": "first",
"lastName": "last",
"credentials": [
{
"type": "password",
"value": "newPas1*",
"temporary": false
}
]
}
Error is:
{
"error": "RESTEASY003210: Could not find resource for full path: http://localhost:8180/auth/public-library/users"
}
It looks like you are using the wrong endpoint, change it to
http://localhost:8180/auth/admin/realms/public-library/users
And keep in mind, the user who is performing the POST request need to have at least the manage-users realm-management role assigned. Otherwise the response will be 403 Forbidden
What you need to do is go to the realm you are using in keycloak. Then go to the users section and select the user you are you using for the request. Under role Mappings, select realm management and assign this user the role realm admin and manage users role. After that, you will be able to make requests

Google Actions SDK Sign-In implicit flow

EDIT: On phone assistant its working now problem just exist in google action simulator
I just try to setup Google Actions SDK account Linking with implicit grant and try to test it in Simulator.
First question is this even possible in Simulator?
To Do so I added at the action console account linking with the type
implicit grant to my action.
The url I used is working.
Now I added a signup request to my action. For testing so if I write signup in simulator the server response with:
{
conversationToken: JSON.stringify(state),
expectUserResponse: true,
expectedInputs: [
{
inputPrompt: {
initialPrompts: [
{
textToSpeech: "PLACEHOLDER_FOR_SIGN_IN"
}
],
noInputPrompts: []
},
possibleIntents: [
{
"intent": "actions.intent.SIGN_IN",
"inputValueData": {}
}
],
speechBiasingHints: []
}
]
}
After this the server didn't request the sign in page route (the address is correct!). It just responds with SignIN intent ERROR :
{
"isInSandbox'": false,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "i think so",
"inputType": "VOICE"
}
],
"arguments": [
{
"name": "SIGN_IN",
'extension': {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "Error"
}
}
],
"intent': "actions.intent.SIGN_IN"
}
],
"device": {
"locale": "en-US"
},
"conversation": {
"conversationId": "1494606917128",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google_\"]"
}
}
Why? Where is the problem? Can I see a error message somewhere?
Here is what happen in the simulator between 3 and 4:
Is it same when you use the phone app? For me it opens an embedded browser with my /auth endpoint, which the simulator doesn’t do.
I am able to make it WORKING after a long time.
We have to enable the webhook first and we can see how to enable the webhook in the dialog flow fulfillment docs
If we are going to use Google Assistant, then we have to enable the Google Assistant Integration in the integrations first.
Then follow the steps mentioned below for the Account Linking in actions on google:-
Go to google cloud console -> APIsand Services -> Credentials -> OAuth 2.0 client IDs -> Web client -> Note the client ID, client secret from there
-> Download JSON - from json note down the project id, auth_uri, token_uri
-> Authorised Redirect URIs -> White list our app's URL -> in this URL fixed part is https://oauth-redirect.googleusercontent.com/r/ and append the project id in the URL
-> Save the changes
Actions on Google -> Account linking setup
1. Grant type = Authorisation code
2. Client info
1. Fill up client id,client secrtet, auth_uri, token_uri
2. Enter the auth uri as https://www.googleapis.com/auth and token_uri as https://www.googleapis.com/token
3. Save and run
4. It will show an error while running on the google assistant, but dont worry
5. Come back to the account linking section in the assistant settings and enter auth_uri as https://accounts.google.com/o/oauth2/auth
and token_uri as https://accounts.google.com/o/oauth2/token
6. Put the scopes as https://www.googleapis.com/auth/userinfo.profile and https://www.googleapis.com/auth/userinfo.email
and weare good to go.
7. Save the changes.
In the hosting server logs, we can see the access token value and through access token, we can get the details regarding the email address.
Append the access token to this link "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" and we can get the required details in the resulting json page.
accessToken = req.get("originalRequest").get("data").get("user").get("accessToken")
r = requests.get(link)
print("Email Id= " + r.json()["email"])
print("Name= " + r.json()["name"])
P.S. You can use the Grant Type as Implicit also instead of Authorisation code.