Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Python class to integrate Boto3's Cognito client so it is easy to login users. With SRP support.
Makes working with AWS Cognito easier for Python developers.
pycognito.Cognito
pip install pycognito
Optional: This environment variable is a dictionary that represent the well known JWKs assigned to your user pool by AWS Cognito. You can find the keys for your user pool by substituting in your AWS region and pool id for the following example.
https://cognito-idp.{aws-region}.amazonaws.com/{user-pool-id}/.well-known/jwks.json
Example Value (Not Real):
COGNITO_JWKS={"keys": [{"alg": "RS256","e": "AQAB","kid": "123456789ABCDEFGHIJKLMNOP","kty": "RSA","n": "123456789ABCDEFGHIJKLMNOP","use": "sig"},{"alg": "RS256","e": "AQAB","kid": "123456789ABCDEFGHIJKLMNOP","kty": "RSA","n": "123456789ABCDEFGHIJKLMNOP","use": "sig"}]}
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id',
client_secret='optional-client-secret'
username='optional-username',
id_token='optional-id-token',
refresh_token='optional-refresh-token',
access_token='optional-access-token',
access_key='optional-access-key',
secret_key='optional-secret-key')
Used when you only need information about the user pool (ex. list users in the user pool)
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id')
Used when the user has not logged in yet. Start with these arguments when you plan to authenticate with either SRP (authenticate) or admin_authenticate (admin_initiate_auth).
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
Used after the user has already authenticated and you need to build a new Cognito instance (ex. for use in a view).
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id',
id_token='your-id-token',
refresh_token='your-refresh-token',
access_token='your-access-token')
u.verify_tokens() # See method doc below; may throw an exception
After any authentication or other explicit verification of tokens, the following additional attributes will be available:
id_claims
— A dict of verified claims from the id tokenaccess_claims
— A dict of verified claims from the access tokenRegister a user to the user pool
Important: The arguments for set_base_attributes
and add_custom_attributes
methods depend on your user pool's configuration, and make sure the client id (app id) used has write permissions for the attributes you are trying to create. Example, if you want to create a user with a given_name equal to Johnson make sure the client_id you're using has permissions to edit or create given_name for a user in the pool.
from pycognito import Cognito
u = Cognito('your-user-pool-id', 'your-client-id')
u.set_base_attributes(email='you@you.com', some_random_attr='random value')
u.register('username', 'password')
Register with custom attributes.
Firstly, add custom attributes on 'General settings -> Attributes' page. Secondly, set permissions on 'Generals settings-> App clients-> Show details-> Set attribute read and write permissions' page.
from pycognito import Cognito
u = Cognito('your-user-pool-id', 'your-client-id')
u.set_base_attributes(email='you@you.com', some_random_attr='random value')
u.add_custom_attributes(state='virginia', city='Centreville')
u.register('username', 'password')
Authenticates a user
If this method call succeeds the instance will have the following attributes id_token, refresh_token, access_token, expires_in, expires_datetime, and token_type.
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
u.authenticate(password='bobs-password')
Authenticate the user using admin super privileges
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
u.admin_authenticate(password='bobs-password')
Sends a verification code to the user to use to change their password.
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
u.initiate_forgot_password()
No arguments
Allows a user to enter a code provided when they reset their password to update their password.
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
u.confirm_forgot_password('your-confirmation-code','your-new-password')
Changes the user's password
from pycognito import Cognito
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
u.change_password('previous-password','proposed-password')
Use the confirmation code that is sent via email or text to confirm the user's account
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id')
u.confirm_sign_up('users-conf-code',username='bob')
Update the user's profile
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
u.update_profile({'given_name':'Edward','family_name':'Smith',},attr_map=dict())
Send verification email or text for either the email or phone attributes.
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
u.send_verification(attribute='email')
Returns an instance of the specified user_class.
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
u.get_user_obj(username='bjones',
attribute_list=[{'Name': 'string','Value': 'string'},],
metadata={},
attr_map={"given_name":"first_name","family_name":"last_name"}
)
Get all of the user's attributes. Gets the user's attributes using Boto3 and uses that info to create an instance of the user_class
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
user = u.get_user(attr_map={"given_name":"first_name","family_name":"last_name"})
Get a list of the user in the user pool.
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id')
user = u.get_users(attr_map={"given_name":"first_name","family_name":"last_name"})
Returns an instance of the specified group_class.
u = Cognito('your-user-pool-id', 'your-client-id')
group_data = {'GroupName': 'user_group', 'Description': 'description',
'Precedence': 1}
group_obj = u.get_group_obj(group_data)
Get all of the group's attributes. Returns an instance of the group_class. Requires developer credentials.
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id')
group = u.get_group(group_name='some_group_name')
Get a list of groups in the user pool. Requires developer credentials.
from pycognito import Cognito
u = Cognito('your-user-pool-id','your-client-id')
groups = u.get_groups()
Checks the exp attribute of the access_token and either refreshes the tokens by calling the renew_access_tokens method or does nothing. IMPORTANT: Access token is required
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
u.check_token()
No arguments for check_token
Verifies the current id_token
and access_token
.
An exception will be thrown if they do not pass verification.
It can be useful to call this method immediately after instantiation when you're providing externally-remembered tokens to the Cognito()
constructor.
Note that if you're calling check_tokens()
after instantitation, you'll still want to call verify_tokens()
afterwards it in case it did nothing.
This method also ensures that the id_claims
and access_claims
attributes are set with the verified claims from each token.
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
u.check_tokens() # Optional, if you want to maybe renew the tokens
u.verify_tokens()
No arguments for verify_tokens
Logs the user out of all clients and removes the expires_in, expires_datetime, id_token, refresh_token, access_token, and token_type attributes.
from pycognito import Cognito
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
u.logout()
No arguments for logout
Get the secret code to issue the software token MFA code. Begins setup of time-based one-time password (TOTP) multi-factor authentication (MFA) for a user.
from pycognito import Cognito
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
secret_code = u.associate_software_token()
# Display the secret_code to the user and enter it into a TOTP generator (such as Google Authenticator) to have them generate a 6-digit code.
No arguments for associate_software_token
Verify the 6-digit code issued based on the secret code issued by associate_software_token. If this validation is successful, Cognito will enable Software token MFA.
from pycognito import Cognito
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
secret_code = u.associate_software_token()
# Display the secret_code to the user and enter it into a TOTP generator (such as Google Authenticator) to have them generate a 6-digit code.
code = input('Enter the 6-digit code.')
device_name = input('Enter the device name')
u.verify_software_token(code, device_name)
Enable and prioritize Software Token MFA and SMS MFA. If both Software Token MFA and SMS MFA are invalid, the preference value will be ignored.
from pycognito import Cognito
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
id_token='id-token',refresh_token='refresh-token',
access_token='access-token')
# SMS MFA are valid. SMS preference.
u.set_user_mfa_preference(True, False, "SMS")
# Software Token MFA are valid. Software token preference.
u.set_user_mfa_preference(False, True, "SOFTWARE_TOKEN")
# Both Software Token MFA and SMS MFA are valid. Software token preference
u.set_user_mfa_preference(True, True, "SOFTWARE_TOKEN")
# Both Software Token MFA and SMS MFA are disabled.
u.set_user_mfa_preference(False, False)
Responds when a Software Token MFA challenge is requested at login.
from pycognito import Cognito
from pycognito.exceptions import SoftwareTokenMFAChallengeException
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
try:
u.authenticate(password='bobs-password')
except SoftwareTokenMFAChallengeException as error:
code = input('Enter the 6-digit code generated by the TOTP generator (such as Google Authenticator).')
u.respond_to_software_token_mfa_challenge(code)
When recreating a Cognito instance
from pycognito import Cognito
from pycognito.exceptions import SoftwareTokenMFAChallengeException
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
try:
u.authenticate(password='bobs-password')
except SoftwareTokenMFAChallengeException as error:
mfa_tokens = error.get_tokens()
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
code = input('Enter the 6-digit code generated by the TOTP generator (such as Google Authenticator).')
u.respond_to_software_token_mfa_challenge(code, mfa_tokens)
Responds when a SMS MFA challenge is requested at login.
from pycognito import Cognito
from pycognito.exceptions import SMSMFAChallengeException
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
try:
u.authenticate(password='bobs-password')
except SMSMFAChallengeException as error:
code = input('Enter the 6-digit code you received by SMS.')
u.respond_to_sms_mfa_challenge(code)
When recreating a Cognito instance
from pycognito import Cognito
from pycognito.exceptions import SMSMFAChallengeException
#If you don't use your tokens then you will need to
#use your username and password and call the authenticate method
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
try:
u.authenticate(password='bobs-password')
except SMSMFAChallengeException as error:
mfa_tokens = error.get_tokens()
u = Cognito('your-user-pool-id','your-client-id',
username='bob')
code = input('Enter the 6-digit code generated by the TOTP generator (such as Google Authenticator).')
u.respond_to_sms_mfa_challenge(code, mfa_tokens)
The AWSSRP
class is used to perform SRP(Secure Remote Password protocol) authentication.
This is the preferred method of user authentication with AWS Cognito.
The process involves a series of authentication challenges and responses, which if successful,
results in a final response that contains ID, access and refresh tokens.
The AWSSRP
class takes a username, password, cognito user pool id, cognito app id, an optional
client secret (if app client is configured with client secret), an optional pool_region or boto3
client.
Afterwards, the authenticate_user
class method is used for SRP authentication.
import boto3
from pycognito.aws_srp import AWSSRP
client = boto3.client('cognito-idp')
aws = AWSSRP(username='username', password='password', pool_id='user_pool_id',
client_id='client_id', client=client)
tokens = aws.authenticate_user()
You must use the USER_SRP_AUTH
authentication flow to use the device tracking feature. Read more about Remembered Devices
Once the authenticate_user
class method is used for SRP authentication, the response also returns DeviceKey
and DeviceGrouKey
.
These Keys will later be used to confirm the device.
import boto3
from pycognito.aws_srp import AWSSRP
client = boto3.client('cognito-idp')
aws = AWSSRP(username='username', password='password', pool_id='user_pool_id',
client_id='client_id', client=client)
tokens = aws.authenticate_user()
device_key = tokens["AuthenticationResult"]["NewDeviceMetadata"]["DeviceKey"]
device_group_key = tokens["AuthenticationResult"]["NewDeviceMetadata"]["DeviceGroupKey"]
The confirm_device
class method is used for confirming a device, it takes two inputs, tokens
and DeviceName
(DeviceName
is optional).
The method returns two values, response
and device_password
. device_password
will later be used to authenticate your device with
the Cognito user pool.
response, device_password = user.confirm_device(tokens=tokens)
The update_device_status
class method is used to update whether or not your device should be remembered. This method takes
three inputs, is_remembered
, access_token
and device_key
. is_remembered
is a boolean value, which sets the device status as
"remembered"
on True
and "not_remembered"
on False
, access_token
is the Access Token provided by Cognito and device_key
is the key
provided by the authenticate_user
method.
response = user.update_device_status(False, tokens["AuthenticationResult"]["AccessToken"], device_key)
To authenticate your Device, you can just add device_key
, device_group_key
and device_password
to the AWSSRP class.
import boto3
from pycognito.aws_srp import AWSSRP
client = boto3.client('cognito-idp')
aws = AWSSRP(username='username', password='password', pool_id='user_pool_id',
client_id='client_id', client=client, device_key="device_key",
device_group_key="device_group_key", device_password="device_password")
tokens = aws.authenticate_user()
To forget device, you can call the forget_device
class method. It takes access_token
and device_key
as input.
resonse = aws.forget_device(access_token='access_token', device_key='device_key')
pycognito.utils.RequestsSrpAuth
is a Requests
authentication plugin to automatically populate an HTTP header with a Cognito token. By default, it'll populate
the Authorization
header using the Cognito Access Token as a bearer
token.
RequestsSrpAuth
handles fetching new tokens using the refresh tokens.
import requests
from pycognito.utils import RequestsSrpAuth
auth = RequestsSrpAuth(
username='myusername',
password='secret',
user_pool_id='eu-west-1_1234567',
client_id='4dn6jbcbhqcofxyczo3ms9z4cc',
user_pool_region='eu-west-1',
)
response = requests.get('http://test.com', auth=auth)
FAQs
Python class to integrate Boto3's Cognito client so it is easy to login users. With SRP support.
We found that pycognito demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.