Authentication dependency injection with password users and Google users - python

I am creating an app that allows users to either login with a username and password, or through Google authentication. I have signup and login working for both flows. This is done by creating two separate login (and signup) endpoints for password and Google users.
I am now working on using dependency injection to allow users to request various endpoints which will decode their JWT and return the data if they are authenticated, as shown here: https://fastapi.tiangolo.com/tutorial/security/get-current-user/
This works fine for users that have logged in with a username and password, since this dependency uses OAuth2PasswordBearer.
However, this of course does not work with my Google users since
They don't have a password
The tokenUrl parameter for OAuth2PasswordBearer is set to my password users' login endpoint.
How can I achieve a get_logged_in_user(token: str = Depends(oauth2_scheme)) function that words both for users who have logged in with a password and those who have logged in through Google?

Related

How to use JWT token in the case of Social authentication. (Django)

Normally JWT flow is when enter Username and password it return a JWT token. using the token we can authenticate APIs.
But when we use social authentication how it will happen..?
When we use social authentication, for example google,
we clicks on login with google >> it give access >> redirect with authorisation code >> it gives open id details like email, first name, last name.
If any one have any idea please share.
Im using python django.

firebase auth sdk login user with email and passworrd

I'm using firebase auth sdk for an application and I'd like to log the user in. I cannot understand how it works.
To create a new user I run this code:
from firebase_admin import auth
....
def create_user(email, password):
user = auth.create_user(email=email, password=password)
return user
Now I'd like to log the user in. The auth doesn't have a method to log in the user. It has a auth.get_user_by_email(email) or some other methods to get user(s), but it has no method to check user's password. My application (API) gets email and password and I need to return the user if the email and password match.
How do I do this using the firebase sdk?
Thank you.
Logging into Firebase happens on the client, not on the server. So the Firebase Admin SDKs don't have a method to sign the user in, but all client-side SDKs (such as the Web/JavaScript SDK) have methods to sign in the user.
If you want to sign in a specific user from your Python code, you can call the REST API, or use a library like Pyrebase that wraps this REST API: https://github.com/thisbejim/Pyrebase#authentication.

How to implement single sign-on django auth in azure ad?

I have a django-based web application, a client requested that we integrate the login with Azure AD, following the documents I managed to integrate with the following flow.
In django the user types only the email, I identify the user and his company and redirect him to the microsoft ad login screen, after login, the redirect uri is activated and in my view I do some validations and authenticate the user on my system. The problem is that every time the customer is going to log in he needs to enter his credentials in azure, would it be possible with the microsoft user_id or the token acquired the first time the user logs in to login? Or another way to log in faster?
This my callback view, called in redirect_uri:
def callback(request):
user_id = request.session.pop('user_id', '')
user_internal = User.objects.filter(id=user_id).first()
company_azure = CompanyAzureAd.objects.filter(company=user_internal.employee.firm).first()
# Get the state saved in session
expected_state = request.session.pop('auth_state', '')
# Make the token request
url = request.build_absolute_uri(request.get_full_path())
token = get_token_from_code(url, expected_state, company_azure)
# Get the user's profile
user = get_user(token) #in this moment i have user microsoft profile, with token and id
# Save token and user
store_token(request, token)
store_user(request, user)
...
if it is possible to login I could store the token or user id in microsoft in my database, so it would only be necessary to login once
I think this is already answered here
Also try this
ADFS Authentication for Django
Even you can try the library in python
Django Microsoft Authentication Backend

Django Social Auth Pipeline-- Checking for Duplicate Emails

So i'm piggybacking on this post here:
Python Social Auth duplicating e-mails for different users
Here's my issue:
I provide a user with ability to signup either via regular email sign up, facebook auth or twitter auth.
I'm also using same package Social Django Auth App for the user login pages.
I realized that a user might try sign up with a Facebook account (associated to one email) and then try again later to register with Twitter (which could have the same email address). Based on the aforementioned post, I added a function to check for duplicate emails like so:
def check_email_exists(request, backend, details, uid, user=None, *args, **kwargs):
email = details.get('email', '')
provider = backend.name
# check if social user exists to allow logging in (not sure if this is necessary)
social = backend.strategy.storage.user.get_social_auth(provider, uid)
# check if given email is in use
count = User.objects.filter(username=email).count()
success_message = messages.success(request, 'Sorry User With That Email Already Exists')
# user is not logged in, social profile with given uid doesn't exist
# and email is in use
if not user and not social and count:
return HttpResponseRedirect(reverse('accounts:sign_up', success_message))
and my pipeline with the function:
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'dealmazing.utils.check_email_exists',
'social_core.pipeline.social_auth.associate_by_email', # <--- enable this one
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
)
UPON Testing--if i go to sign up with Twitter account of an already registered email address--it works. YAY!
BUT the main issue comes when i go to try to login via using either Facebook or Twitter. The function is checking on those logins as well and spitting me back the 'Email Allready Exists..' error.
So I somehow need to decipher between a login and a registration, but I'm having trouble finding how i actually do this with the social auth package.
Any ideas?
The difference between login and register is up to your project, it looks like in your scenario, a user landing in your pipeline function that matches an email in your DB should be considered like a login attempt and not a new singup. That's basically the functionality of associate_by_email method.
You might see the potential risk in this when a user uses a service that doesn't validate the email addresses, they can take control over somebody else account. You can mitigate this by doing validation on your end after any new social account is added, or by trusting services that are known to validate emails on their ends.
I would say, that you have to remove from the pipeline
'social_core.pipeline.social_auth.associate_by_email'
Reason: your application is not supporting unique user emails in User data model, and you are getting yourself into trouble. If you are not verifying user emails, then the trouble might be even bigger.

Django login only using username and hash

I want to implement software client which will interact with django server. I need users loging in on client.
Is it possible check user is in database and its password, only with username and it's password ? Something like:
if user_valid(username, password):
do something;
I don't want to send open password, is it possible to send only it's hash? How can I obtain valid hash? The auth method in this case shoud be:
if user_valid(username, password_hash):
do something;
Check out https://github.com/jpulgarin/django-tokenapi
Basically you'll need to generate a token based on the user .. in the example below, the author is using user primarykey and password.
Example:
https://github.com/jpulgarin/django-tokenapi/blob/master/tokenapi/tokens.py#L15
Following that.. you can implement a custom authentication backend .. which will allow user to login using the generated token.
Example:
https://github.com/jpulgarin/django-tokenapi/blob/master/tokenapi/backends.py#L13
More information on custom authentication backend
https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#customizing-authentication-in-django

Categories