Find username in Cognito - amazon-web-services

I am managing membership with Cognito in my app. By the way, cognito looks for a password but does not provide a username lookup. Am I not looking for it? Or doesn't it provide functionality? So I try to find my id by storing it in mysql. How do everyone find usernames in Cognito?

You might use AdminGetUser to get a user from a given pool.
In python is like:
from boto3 import client
_cognito = client('cognito-idp')
user = _cognito.admin_get_user(
UserPoolId='Your-Pool-Id',
Username='Your-User',
)
As suggested by #joe in the comments, you can also use GetUser but you will need an access token.
from boto3 import client
_cognito = client('cognito-idp')
user = _cognito.get_user(
AccessToken='Your-Access-Token',
)

If your user is authenticated and you have ID and Access JWT tokens for them you can decode those and they contain the user attributes like sub, email, etc. which might provide the information you need. There's example code here on how to decode each token but basically they're base64 encoded in three period delimited sections like aaa.bbb.ccc so you just split the string on '.' and base64 decode each section.

Related

How to disable a user's password in AWS using boto3

I am auditing user passwords in AWS using boto3 and I'm not finding a way to accomplish the following CIS Benchmark: "Ensure credentials (with password enabled) unused for 90 days or greater are disabled."
I have the code to pull the password age and to pull the last time the password was used, but I do not find anything to make inactive a password.
For access keys (but not passwords), we have the following:
client = session.client('iam')
... (get user and keyid) ...
last_used = client.get_access_key_last_used(AccessKeyId=keyid)
... (determine the age of the key) ...
if age >= 90:
client.update_access_key(AccessKeyId=keyid, Status='Inactive', UserName=user)
Does anyone have any pointers?
delete_login_profile is the one you should use if you want to delete the password for the specified IAM user, which terminates the user's ability to access AWS services through the AWS Management Console.
However to prevent all user access (including CLI and API access) you must also either make any access keys inactive or delete them.
From Boto3 Documentation:
Warning
Deleting a user's password does not prevent a user from accessing AWS
through the command line interface or the API. To prevent all user
access you must also either make any access keys inactive or delete
them. For more information about making keys inactive or deleting
them, see UpdateAccessKey and DeleteAccessKey.
If you want to change the password, you should use update_login_profile boto3 API. If you want to disable the password, you need to use delete_login_profile.
boto3 documentation for update_login_profile can be found here.
boto3 documentation for delete_login_profile can be found here.
Thanks to the responders, delete_login_profile followed by a password reset using create_login_profile is exactly what I needed. I saw it in the docs, but "delete" just sounded too scary.
def getPassword(client, user):
''' get the password data from aws '''
try:
response = client.get_login_profile(UserName=user)
return response
except client.exceptions.NoSuchEntityException as e:
print(e)
return ''
# setup the client handler
client = session.client('iam')
# set the user
user = 'some.user'
# if the user has a password, execute this code block
if getPassword(client=client, user=user):
... code to test the password age here ...
... if it's too old, then ...
# remove the login_profile/password/ability to use the Console
client.delete_login_profile(UserName=user)
# set the new password
passwd = raw_input('Enter New Password: ')
# create the new login_profile with the new password and force the user to change the password on the next login
client.create_login_profile(UserName=user, Password=passwd, PasswordResetRequired=True)

Revoking tokens using Django rest-framework-jwt

I'm thinking of allowing a user to revoke previously issued tokens (yes, even though they are set to expire in 15 minutes), but did not find any way to do so using DRF-jwt.
Right now, I'm considering several options:
Hope someone on SO will show me how to do this out-of-the-box ;-)
Use the jti field as a counter, and, upon revocation, require jti > last jti.
Add user-level salt to the signing procedure, and change it upon revocation
Store live tokens in some Redis DB
Is any of the above the way to go?
We did it this way in our project:
Add jwt_issue_dt to User model.
Add original_iat to payload. So token refresh won't modify this field.
Compare original_iat from payload and user.jwt_issue_dt:
from calendar import timegm
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
class CustomJSONWebTokenAuthentication(JSONWebTokenAuthentication):
def authenticate_credentials(self, payload):
user = super(CustomJSONWebTokenAuthentication, self).authenticate_credentials(payload)
iat_timestamp = timegm(user.jwt_issue_dt.utctimetuple())
if iat_timestamp != payload['iat']:
raise exceptions.AuthenticationFailed('Invalid payload')
return user
To revoke a token you just need to update the field user.jwt_issue_dt.

Logout or end session using itsdangerous signing

If I create a token for my API like this:
def generate_auth_token(self, **kwargs):
s = Serializer(app.config['SECRET_KEY'], expires_in = 172800)
return s.dumps({ 'id': kwargs['user_id'] })
How can I end a user's session?
You can't if that's the only information in the token. You can solve this by adding more information to the token payload, and possibly storing extra information about valid tokens server side.
For example, you could store a hash of the email and password, so if either changes, the hash will not compare anymore
from hashlib import md5
from werkzeug.security import safe_str_cmp
# generate the hash and store it in the token along with the id
hash = md5('{}{}'.format(user.email, user.password).encode('utf8')).hexdigest()
###
# load the user from the id in the token and generate its hash
hash = md5('{}{}'.format(user.email, user.password).encode('utf8')).hexdigest()
# then compare the hash in the token to the hash for the user
if not safe_str_cmp(hash, token['hash']):
# don't log in user
This is done in a hash rather than just including the email and password directly because the token is signed but not encrypted.
If you want to be able to invalidate all tokens without changing the email or password, you can store some random key per user and add that to the hash. Generating a new random key will invalidate all previous tokens.
You could also take this even further and just store the full tokens server side, removing them on logout so they can't be used again.

User creation from request POST through crul/http.

I am trying to create users from a POST request sent from curl/httpie commands. Users are created in the User Model, but the password is stored in raw string format. This is what i do.
http POST http://127.0.0.1:8000/user/ username=taco password=123
This creates a User with the following credentials.
Now when I enter my admin site, and click on the details of user created. The password shows like this.
Invalid password format or unknown hashing algorithm.
Raw passwords are not stored, so there is no way to see this user's password, but you can change the password using this form.
I have automatic token creation system on user post_save. Token is also created. but when i put.
http POST http://127.0.0.1:8000/obtain/ username=taco password=123
url***/obtain goes to views.obtain_auth_token imported from rest_framework.authtoken.views from which I receive the token for the specified User.
but I get a error saying..
"non_field_errors": [
"Unable to log in with provided credentials."
]
I basically want to signup(create) a user from terminal(http/curl) and obtain their token from "/obtain"
No worries It so happened that you cant post password in raw string.
so by capturing the .username and .password from the query paramenter. I wrote a a create user code on my view , and set the password using .setpassword().

Django-social-auth google oauth token usage

I'm using Django-socila-auth plugin. It uses google API for Oauth 1.0 Authentication. Question is have anybody used it with google python API (gdata). I mean how to apply auth session_token, stored in django-social-auth model to my api call.
Can you help me with code to get this token from model and apply to gdata.PhotoService() instance. For now it is like this:
#getting model instance from django-social-auth model
association = Association.objects.get(user=request.user)
google_session_token=association.handle
google_secret=association.secret
#token string from django-social-auth
#model Association field "handle" looks like:
#google_session_token = '.......XG84PjwytqJkvr8WQhDxm1w-JplWK5zPndSHB13f.........'
gd_client = gdata.photos.service.PhotosService()
gd_client.debug = 'true'
gd_client.auth_token = google_session_token
#image.image is a file field, but problem not in this.
#it tries to send file in debug text.
#It just recieves 403 unauthorised callback.
photo = gd_client.InsertPhotoSimple(
'/data/feed/api/user/default/albumid/default', 'New Photo',
'Uploaded using the API', image.image, content_type='image/jpeg')
I'm recieving error
403 Invalid token string.
I understand that it needs secret too but how to apply it to API for auth?(To receive authorization to post photos.). BTW I added Picassa feed URL, as an option string for social-auth to ask permissions, so token I have asks for Picassa feed permissions when authorizing with google.
BTW. Google tutorial I've used is: here
I understand it's Oauth 1.0 rather than AusSub, but question is:
how to authenticate with token and secret I have and post a photo with this permission?
Just to answer my own problem. I used wrong way to do it, because problem in 'gd_client' and AuthSub.
It must check token on server. And it can not do it on localhost. You need to look ahead to Oauth/Oauth2 for better debugging and so on... No matter that it is much complex than AuthSub