MVC Identity Custom Token and Validation - asp.net-mvc

I have UserManager and am making a custom ApplicationUserManager. How do I incorporate a custom token provider and validator for something completely different than validating your account?
The way I want to use this is when the parts manager creates an order, it sends an email to all office managers. The managers all need to have a custom token and in this email, it has two buttons, a reject button and an approve button. Each will have a link back to my website, flagging the order appropriately.
I could generate a random string or numbers and save it to the database, one for each approve and reject, and each manager would get basically the same email with different userIDs in the callback url to tell the who approved or rejected the order.
I would rather create a function in the ApplicationUserManager somewhat like the .GenerateEmailConfirmationTokenAsync function and then .ConfirmEmailAsync, but for .GenerateOrderApprovalTokenAsync and .GenerateOrderRejectionTokenAsync. That way each user will have a completely different token that will expire after x amount of hours.
Can anyone point me in the correct direction. All the custom tokens I see online are all for validating your account.

Related

Sync multiple email accounts at the same time

We have an app that allows us to signup using one email id and can add/ link another email id. When we enter the home page after signup, it should show the teams/challenges created using the first email id on the top and the teams created using the second email id on the bottom. We are thinking of using firebase for backend. Is it possible to have two email ids active at the same time?
No. You must go outside BaaS, particularly Firebase, as you have mentioned. You can consider making your own backend server for that feature.
What Firebase can provide you is the ability to have a single email address connected to different sign-in methods.
ref: https://support.google.com/firebase/answer/9134820?hl=en&ref_topic=6386702
If you're using Firebase Authentication to sign in users, then no, it's not possible to have two accounts signed in to a single device at a time. If you sign in a second account, then the first one will be automatically signed out.
If you want to "link" two accounts in such a way that they can query each others' data, you're going to have to establish that relationship in your database or custom claims, and use that in security rules to allow shared access to data.

How do I save a user to a database after OAuth with Google Sign In API?

My question is similar to What data can I save in my database to verify a user with Google sign in API?
I've built Google Sign In correctly and I get a response from the API like this:
{
"iss":"https://accounts.google.com",
"at_hash":"xxx",
"aud":"xxx.apps.googleusercontent.com",
"sub":"xxx",
"email_verified":true,
"azp":"xxx.apps.googleusercontent.com",
"email":"xxx#gmail.com",
"iat":xxx,
"exp":xxx
}
The SO link above says to save the sub field as this is a unique identifier. I can save the email/sub no problem. My question is: How do I allow this user to sign in next time with an email/password form, if they choose to do this, versus OAuth? I guess I could force them to sign in thru OAuth, then verify they're signed in and have them create a password, but I don't know if that's the best way to do this.
The "sub" parameter is only guaranteed unique for the "iss" parameter. So the combination of "iss" and "sub" is globally unique.
If you MUST store a password you will need to ask the user. Some apps put in a random-complex password for every user as some application frameworks require a password. This may be helpful if they forget they used Google to sign in for you to do you due diligence in assigning a temporary password for the user with the email address.
You should of course consider that the email address is globally unique at any given time, but could be reassigned in some cases.

ASP.NET Membership unconfirmed user accounts

I'm writing an ASP.NET MVC application, which uses the Membership database to store user registrations. I use email addresses as usernames. When a user registers in my app, I send out an email-confirmation to the address they have used during registration. i.e. I send out an email with a link, which the user is supposed to click, to verify that the address belongs to him.
Until that link is clicked, the account remains 'Unconfirmed' (i.e. EmailConfirmed column equals False). Which means, the account is created, just not active.
How do I deal with a hacker who brute-force creates accounts? I see two big problems here:
Ever-increasing size of the Membership database. A single user, from
a single computer is not a threat, but what if he has 'zombie'
computers?
If User1 creates account with User2#example.com email and
User2 ignores the activation email, the account will essentially
remain locked (unconfirmed), but existing. If User2 decides later to
actually create an account, they can't use their email to register
(account already exists) and they can't Reset Password either -
because even if they reset the password, that does not necessarily
Activate the account.
As for 2) I see a couple of options:
Set expiration date on unconfirmed accounts - i.e. allow the username/email to be claimed again, if the email is not confirmed with 24hrs
Modify my Reset Password method to also activate the account, if it has not been activated. Is that a good idea? I mean, the person would receive an email for that, which is essentially a confirmation, if they click the reset password link in it.
Anything else?
What about 1)? How do I protect myself against bulk create of accounts? Aside from limiting 1 account per IP, per day, using code.
One simple way to deal with this kind of problem is crude but effective.
I usually add an additional field to the form that doesn't form part of what I need - but has a legitmate sounding name like 'Company' - and then I hide it from screen view using CSS. Real user's will never see this on screen, but a bot crawling through the HTML will find it.
Then, when the form is submitted, first I check to see if that form field has a value. If it has - I stop the page from executing any further or just return an HTTP Error as in 99.9% of times only a bot would have filled out that field - not a real user.
//anti-bot measure
if (!String.IsNullOrEmpty(Company.Text))
{
HttpContext.Current.Response.StatusCode = 400;
HttpContext.Current.Response.Status = "400 Bad Request";
HttpContext.Current.Response.End();
}
//carry on processing the form...
I've been using this technique on forms for several years and it's been extremely effective!

Can email address not verified in oauth2?

I know not all providers give out user email address, but assuming if they use oauth2 and the email field is not empty, can I say that email address must be verified ?
Using plain OAuth 2.0 (plus provider specific extensions that would be required for this scenario) this is not possible in a generic way. Using OpenID Connect, which is a standardized extension of OAuth 2.0 that provides login semantics this is possible through the standardized email_verified claim that is provides as part of the so-called ID token, and something can be requested explicitly in the authentication request.
Ofcourse it's possible. First you would have an intermediate form that would get redirected to from any provider, and fills in the fields, including email if available, if not available, then it will be blank for the user to fill it in and submit the form. You have to structure your application so that if a email address field is available and not empty and a valid email populate it in the field and allow the user to submit the form, then you would send the email verification email and perform any other step that you want when a user creates an account.
I would separate it out into events, and fire events when a user account is created. Then attach some listeners to listen to user account created event.
You can then create new event listeners and attach them to the event as needed.
Some good videos about Commands and Domain Events are available on Laracasts https://laracasts.com/series/commands-and-domain-events

Authenticate registering users against already existing User profiles on Server

I am busy with a Web Api 2 project in VS 2013. We have a number of established applications, and a couple hundred clients with in turn thousand's of users registered at each client.
I am assigned with creating a Mobile App (Cordova/Phonegap), but before I can do this I need to create an API that can handle http Requests from the app.
We have a large database with 173 tables including a user table. This database exists at each client (with their own users). I have imported the default AspNet... tables into our database, changed the connection string and have successfully managed to register users on our database.
My questions is this: Is it possible add additional registration requirements? e.g. in addition to Email, Password, (ConfirmPassword), I'd like to add:
1) Mobile Number
2) Identity number
so that they are also written to AspNetUsers, and then somehow create a foreign key link to my existing USERS table, let's say on ID number provided by the user?
The idea is to not let any user register with the mobile APP that is not already registered on the database.
So, how it should be able to work in my head is not necessarily correct, but here is a summary below:
1) User download app from app store.
2) App shows register/login screen, user register with Email, password, ConfirmPW, MobileNr, ID
3) App sends HTTPS Post request to API with above info.
4) API gets info, before binding to model and writing to db, first does a query to existing User table. If a user exists with ID and mobile Number, then AspNetUsers record is created (with FK reference to Users table). If not, user is not allowed to register, and message is returned, e.g. You need to be a Client of "CompanyName" to register.
5) After this, user logs in and uses Bearer token etc. (default log in way).
I know this is not necessarily how it will work in practice, but can something like this be done. I don't want to re-invent any wheel, only add what listed above. Thanks in advance.
Yes, you can customize the User information. You need to customize the IdentityUser class. Here is a great tutorial on how to do it. I even managed to change the normal Id in the AspNetUsers table (which is nvarchar by deault) to an int.

Resources