-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cognito client crendetials flow #1528
base: main
Are you sure you want to change the base?
Changes from all commits
603634b
e5f1693
d4deffa
4bf6f74
4d49609
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -331,6 +331,69 @@ Ensuring this match is crucial for the proper functioning of the authentication | |
{"access_token": "eyJ0eXAi…lKaHx44Q", "expires_in": 86400, "token_type": "Bearer", "refresh_token": "e3f08304", "id_token": "eyJ0eXAi…ADTXv5mA"} | ||
``` | ||
|
||
### Client credentials grant | ||
|
||
The client credentials grant is designed for machine-to-machine (M2M) communication. | ||
In contrast, the authorization code and implicit grants provide tokens to authenticated human users. | ||
The client credentials grant allows for scope-based authorization from a non-interactive system to an API. | ||
Your app can directly request client credentials from the token endpoint to receive an access token. | ||
|
||
To request the token from LocalStack the correct URL is `http://cognito-idp.localhost.localstack.cloud:4566/_aws/cognito-idp/oauth2/token`. | ||
In case that there is more than one user pool, LocalStack detects the right one by inspecting the `clientId` of the requests. | ||
|
||
Here is an example on how to set it up: | ||
|
||
```sh | ||
#Create user pool. | ||
export pool_id=$(awslocal cognito-idp create-user-pool --pool-name test --username-configuration "CaseSensitive=False" | jq -rc ".UserPool.Id") | ||
|
||
#Create client user pool with a client. | ||
export client_id=$(awslocal cognito-idp create-user-pool-client --user-pool-id $pool_id --client-name test-client --generate-secret | jq -rc ".UserPoolClient.ClientId") | ||
|
||
#Retrieve secret. | ||
export client_secret=$(awslocal cognito-idp describe-user-pool-client --user-pool-id $pool_id --client-id $client_id | jq -r '.UserPoolClient.ClientSecret') | ||
|
||
#Create resource server | ||
awslocal cognito-idp create-resource-server \ | ||
--user-pool-id $pool_id \ | ||
--identifier "api-client-organizations" \ | ||
--name "Resource Server Name" \ | ||
--scopes '[{"ScopeName":"read","ScopeDescription":"Read access to Organizations"}]' | ||
|
||
``` | ||
|
||
Then you could retrieve the token from your application like this: | ||
|
||
```python | ||
import requests, os | ||
from requests.auth import HTTPBasicAuth | ||
|
||
def get_access_token_with_secret(): | ||
client_id = os.environ['client_id'] | ||
client_secret = os.environ['client_secret'] | ||
scope = 'api-client-organizations/read' | ||
url = 'http://cognito-idp.localhost.localstack.cloud:4566/_aws/cognito-idp/oauth2/token' | ||
|
||
|
||
headers = { | ||
'Content-Type' : 'application/x-www-form-urlencoded' | ||
} | ||
|
||
auth = HTTPBasicAuth(client_id,client_secret) | ||
|
||
payload = { | ||
'grant_type': 'client_credentials', | ||
'client_id':client_id, | ||
'scope':scope | ||
} | ||
response = requests.post(url,headers=headers,auth=auth,data=payload) | ||
|
||
print(response.content) | ||
|
||
if __name__ == "__main__": | ||
get_access_token_with_secret() | ||
``` | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that it would be better to have a sample code in which the Cognito client is created in the Python code, from which you could extract the client ID and secret, and then do the token request. The sh would only need to create the pool. I say this because that may be a more common scenario, normally you would create as many apps as M2M users are in your system. |
||
## Serverless and Cognito | ||
|
||
Furthermore, you have the option to combine Cognito and LocalStack seamlessly with the [Serverless framework](https://www.serverless.com/). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take into account that if the LocalStack user has setup LocalStack as a separate container to their system, they won't be able to get the variables exported here.
What we did was have a local.env file in which the variables were defined (e.g. user pool id). Then pass that to the LocalStack container in the Environment section. Then, in the app use that same local.env to have the same environment information in both containers.
When creating the pool and so on, it would be cool to remind people that you can setup the custom_id, instead of letting LocalStack generate it.