When using GoogleWebAuthorizationBroker.AuthorizeAsync the user can click on the wrong email address - google-oauth

We're using this library Google.Apis.Auth.OAuth2 to request the user to enter oauth credentials.
https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth
This line
var precreds = GoogleWebAuthorizationBroker.AuthorizeAsync(
clientSecret,
scopesList,
emailAddress,
CancellationToken.None,
new FileDataStore(AuthStorageDir)
);
var creds = await precreds;
This will popup a browser and request the user to click on the correct oauth account.
The issue is the emailAddress. In the documentation some places show its being set to "user" and other places say "the user to authorize". We're using the latter interpretation and are providing an email address. But the user could click on a different email address.
Does anyone know what is the correct interpretation?
If we are correct and an email address can be provided, is there a way to detect the email address they clicked on? and then popup a warning message.

I was also wondering what this user information is in GoogleWebAuthorizationBroker.AuthorizeAsync and was searching for an explanation as it is documented very poorly. I think I found the answer in the comments of the following topic: Check if user is already logged in
It is only an information about local users and has nothing to do with the user authenticated against the api. It only enables you to switch users in your application if you need this e.g. For every user an inidividual response file ist stored on your machine: C:\Users\WindowsUser\AppData\Roaming\Google.Apis.Auth\Google.Apis.Auth.OAuth2.Responses.TokenResponse-AuthorizeAsyncUser.
I will check this today in the evening.

Related

How do I change an ASP.NET Identity user's email WITHOUT requiring an email confirmation?

We have many non-tech-savvy users who find it very challenging to use the regular method of changing their email (click a link on the log-in page, enter their email, check their inbox, click the link in the email to confirm). We would like to allow the site admins to be able to change the emails directly, without requiring the users to do anything.
I realise that this has certain dangers, but we have checks in place to ensure that we are going to use the correct new email.
It seems that if I have the existing user from the database and the modified one from a <form> on the admin page, I can just do this...
existingUser.Email = modifiedUser.Email;
existingUser.NormalizedEmail = modifiedUser.Email.ToUpper();
existingUser.UserName = modifiedUser.Email;
existingUser.NormalizedUserName = modifiedUser.Email.ToUpper();
_appDbContext.Users.Update(existingUser);
await _appDbContext.SaveChangesAsync();
This does seem to work (with one caveat, see below), but given that I've never seen recommend this, and every example I've seen creates a token and uses UserManager.SetEmailAsync, I'm wondering if I've missed something.
The one caveat that makes me even more suspicious is that once or twice when I've tried the above, it's created a new user with the same details as the existing one, but the new email. I can't reproduce this, so can't say for definite what causes it.
Anyone able to comment on the best way to handle this? Thanks.
You can set and confirm the email without sending any email like this. Use the UserManager provided by ASP.NET Core Identity:
// set the email on the user, but don't send any email
await _userManager.SetEmailAsync(currentUser, newEmailAddress);
//generate an email confirmation token
var emailConfirmationToken = await _userManager.GenerateEmailConfirmationTokenAsync(existingUser);
//confirm the new email right away
result = await _userManager.ConfirmEmailAsync(existingUser, emailConfirmationToken);

Send password to new user

I would like to ask some questions about password security. In my software the admin can create a new user setting the password and the username. I believe sending the password in plain text in an email is not a very good idea, so I’m thinking about sending a link that redirect the user to a page where they can set up their password. This link should expire after few hours as well. On my login form I’ve also have the option “forgot password” how can I prevent that a user doesn’t use it until they create the new password? How would you do it?
A password reset link is technically exactly the same as a registration link, both are relying on the "fact" that only the owner of the email address can read the link. So there is no reason to prevent a password reset when the user did not yet login.
The usual workflow is slightly different though, usually the user makes the first contact with the site and on the register page (s)he is asked to enter a password.

Attaching additional info to a Google user

Is it possible to add additional info to a Google user, during creation, on a Google Domain?
We have a range of users, that we identify by their email ("username#domain.com"). Some of the users gets to pick a new email, like with their initials, instead of the autogenerated username.
This causes a issue, since we are using a webservice (that we have no controll over), this webservice provides only the users real name, and then their autogenerated username, but not "custom" email with for example the users initials.
So when the user from google comes with his login info, I cant match that user with the userdata from the webservice.
If it was possible to attach the autogenerated username to the google user, it could be matched that way. But i havent been able to find anything about adding custom info like this, to a Google Domain user.
We solved this issue, by adding an alternative email with the autogenerated username + google domain on creation of the Google user.
We then checked the email of the user trying to log in, and if it didnt match, we then checked his alternative email for matches.

facebook one-login authentication

Im adding facebook one-login to my website. Just wanted to get some feedback from people who have already implemented it.
At the moment im allowing user to login to my site using fb:login, providing they have a valid account on fb and login successfully, if the same email address thats returned from fb matches my email address I hold in my own database, they will automatically be logged in to my site.
The problem I have is, im finding hard having just the email as my main authentication between the user and the my site. For those who have already implmented this, could you please share some of you loggic (theory) on how you autenticate the user when you're logging them onto your site.
I had the same problem than you. I had users in my database with their name and email address and I wanted to add the Facebook connect plugin.
Now, on the login page, I let users choose between standard and Facebook login. If one choose Facbook login I retrieve his Facebook ID with the Facebook PHP SDK (see on github) :
$facebook = new Facebook(...);
$id = $facebook->getUser();
If I have this Facebook ID in my records, I log the user in.
If not, I retrieve his email adress :
$profile = $facebook->api('/me');
$email = $profile['email'];
If I have this email in my database, I store the facebook ID in that record (for the next time) and I log the user in.
If not, I create a new record with the Facebook ID and the email. After that, the user can set a password in his settings to be able to log in with the standard login (without Facebook).
You may want to check the example of the Facebook PHP SDK out to better understand how the flow works.
Hope that helps.
I have also done this. I have now understood that you do you want to match the email address that if user changes his email address you want to update it. Its simple solution is that store the user information in your database. What I have done, I store the user profile id returned by the facebook as user name and by converting into md5 I store the same profile ID as password and email adress returned by the user. Now every facebook user has its unique id in my database. Whenever user comes to my site and logins with facebook, There are two cases
1- I compare the profile id with my database and if record found I always update the email address in that particular field returned by facebook.. Now I can have the latest email address of the user. 2- if the user is not in my database then I insert the record by applying the above method.
Hope it will help you

Forgot Password: what is the best method of implementing a forgot password function?

I'm wondering what the best method is for creating a forgot password function on a website. I have seen quite a few out there, here are a few or combination of:
passphrase question / answer (1 or more)
send email with new password
on screen give new password
confirmation through email: must click link to get new password
page requiring user to enter a new password
What combination or additional steps would you add to a forgot password function? I'm wondering about how they request the new password and how they end up getting it.
I'm operating on the principal that the password cannot be retrieved; a new password must be given/generated.
Edit I like what Cory said about not displaying if the username exists, but I'm wondering what to display instead. I'm thinking half the problem is that the user forgot which email address they used, which displaying some sort of "does not exist" message is useful. Any solutions?
I personally would send an email with a link to a short term page that lets them set a new password. Make the page name some kind of UID.
If that does not appeal to you, then sending them a new password and forcing them to change it on first access would do as well.
Option 1 is far easier.
A few important security concerns:
A passphrase question / answer actually lowers security since it typically becomes the weakest link in the process. It's often easier to guess someone's answer than it is a password - particularly if questions aren't carefully chosen.
Assuming emails operate as the username in your system (which is generally recommended for a variety of reasons), the response to a password reset request shouldn't indicate whether a valid account was found. It should simply state that a password request email has been sent to the address provided. Why? A response indicating that an email does/doesn't exist allows a hacker to harvest a list of user accounts by submitting multiple password requests (typically via an HTTP proxy like burp suite) and noting whether the email is found. To protect from login harvesting you must assure no login/auth related functions provide any indication of when a valid user's email has been entered on a login/pass reset form.
For more background, checkout the Web Application Hackers Handbook. It's an excellent read on creating secure authentication models.
EDIT: Regarding the question in your edit - I'd suggest:
"A password request email has been
sent to the address you provided. If
an email doesn't arrive shortly,
please check your spam folder. If no
email arrives, then no account exists
with the email you provided."
There's a trade-off being made here between ease of use and security. You have to balance this based on context - is security important enough to you and your users to justify this inconvenience?
Send email with new password.
FORCE a password change when they arrive and key in the new password.
This ensures that the person who wanted the password will be the only only getting in to the account.
If the email is sniffed, someone could get in to the account (of course), but the real party will discover this immediately (as their password you just sent them doesn't work).
Also send confirmations of password changes to the users.
If someone get the new password, and then an email saying "thanx for changing the password", they're going to be rather puzzled and will talk to an admin if they didn't do it.
Using the email verification/password reset link will give you better security.
If you look around this is how most websites do it and people are pretty used to this verification, so I'd recommend using this type of authentication.
I would think (gbrandt's) Option 2 would be a great method if it is combined with some personal information you already have for the user. i.e date of birth.
When the user requests a new password (reset) via entering his email address, he also has to enter a correct date of birth (or something else) before the password is reset and a new one is emailed to the user.
Only those who know him well can possibly annoy him by resetting his password! It cant be a stranger or a bot
Upon 5 or 7 bad email-address & date of birth combinations the user is emailed that his password has been requested to be reset and has failed due to an incorrect credential. Then password resetting for that account is suspended for 24hrs or any desired period.
(if too many users contact the webadmin regarding this email he'll know someone is trying to maliciously attain information from your website/app)
What do you guys think?
Option 1. is not a good idea, as generally his becomes easily guessable by others. Sarah Palin's personal email (Yahoo I think) was hacked in this way by a third party.
The other options are better and previous posts have outlined the detail.
The idea I was thinking about was to sign the data in the link that is sent to the user. Then, when the user clicks the link and the server receives the call, the server also gets the encrypted part and can validate that the data was untouched.
I have implemented a JAVA project for this use case. It is on GitHub, open source. It answers your question perfectly... implemented in Java.
As for the link in the email - it generates the link, plus validates it upon usage.
There are explanation for everything (and if something is missing - let me know...)
Have a look: https://github.com/OhadR/Authentication-Flows
See a Demo here.
This is the client web-app that uses the auth-flows, with the README with all explanations. it directs you the implementation: https://github.com/OhadR/authentication-flows/tree/master/authentication-flows