How can I authenticate a user from an email link? - autologin

Our web app. sends reports out to users which contain links that point to various items within our web app. (specific records). Users ordinarily have to login to our system to access it, so I am wondering what the best methods are of allowing one of these links to direct the user to the area of the system, without them having to repeatedly login.

When you create a link, you can note which user this link is for. When user clicks on the link, fetch information for the user. Guid in your url would guarantee that no other person can guess path for that users data. This will not technically authenticate a user. But will allow them to see data you need.

First of all it's bad idea to distribute user credentials even to a known email address.
You can generate a unique key for each customer and insert it in query string of included URL in the email. once user clicks on the sent URL, system discovers which user is dealing with and authenticates user. After successful authentication process it really makes sense if you disable the sent unique key.

Related

How to link logged users to their data, retrieve and update them in MySQL table

This is the my web-app "User Settings" page.
I have simplified it to a minimum to better highlight the problem.
To authenticate users I use Auth0, I wanted to use the sub claim user_id to identify the users inside my MySQL database for update and retrieve user's info. Unfortunately the user_id is different for each provider, for example, if the same user with the same e-mail logs-in via Auth0 he gets a user_id if he does it via google he gets another one.
I thought about using email to link logged user to his info.
The problem is in my API. Before the change it was "localhost: 8080 / api / users /: id"
each time it created a new id and in any case it was impossible to recover the data of the single user. Now that I have replaced "id" with "email" my API has also changed in "localhost: 8080 / api / users /: johnsmith#xxx.com".
Before:
After:
In a few words, the request url on the client side has also changed.
I would like to make sure that the GET and PUT requests are made based on the e-mail of the logged user without going to modify the whole back-end.
Sounds like something is wrong with how you authenticate users. If you have multiple ways to authenticate a user, those methods need to be in a one to many relation with the user. For example each user has a list of auth-methods, and whenever an authentication is made you check your table of authentication methods and find the one user it maps to.
Im not sure if you are doing this yourself or if the framework you are using is handling that, but it sounds like you need to change the model to allow many Auth methods for a single account.
Also you could use email, but that is also an "old" way of uniquely identifying users almost every single person has multiple active email accounts nowadays, so you should also have a one-to-many relation for users to emails. What if the user has different email accounts for their Facebook and Google accounts?
See account linking here: https://auth0.com/docs/users/user-account-linking
It is dangerous to trust that the external providers are truthful about what email belongs to who. What if I open a new account using someone else's email on one of the providers? Then I can log into that users account in your application, which is a pretty big security risk.

Is there a way to get a second user to authorize an action without the logged in user seeing their details in the request header?

A strange situation that I am unable to find other people having to deal with. We are using Microsoft AspNetCore.Identity to handle our authentication. Everything is working fine.
The problem is that for a user to perform certain actions, they MUST get another user to 'sign' that action. This act of signing of course requires that other user to use their user name and password to sign the action.
The issue with this is that the other user's details are readily visible in the request payload. So if I am sneaky, I can open the developer tools in my browser (and hide it), then ask my admin to come and sign my action, and when they have gone i can go to the network tab and see their username and login in plain text!
Of course this is all over https but still, we can't allow one user to see another's sensitive information.
How are we to manage to allow a second userB to 'sign' an action for userA while in user A's active session, while removing the capacity for userA to steal userB's credentials??? Any ideas? (Front end is angular.js)
I imagine it's a big rework, but instead of having the "admin" sign the request on the user's machine, the admin could receive a "user A requires this action to be signed, proceed? [ok] [cancel]" on their account, the action would be stored in the database (perhaps temporarily?) & then all of the sensitive information is kept within each user's session with no cross over.
Then the authentication of who is permitted to approve actions can be handled in the backend via standard identity methods.
The user's "Please wait while an admin signs this action" modal (assumption) could then poll an API to determine the status of the action and then proceed once accepted.
I second #justcompile's answer if you need an authorised and authenticated user to sign/confirm the action, more work but the only secure way.
If you just need a second pair of eyes to confirm you could message a private group or slack channel that only "authorised" people have access to with a one-time URL containing a token (that maybe expires after a period of time too).
Assuming admins only access that channel they can follow the link, the app can validate the token and confirm the action.
Saves a second (admin) user logging in on their own machine and the need to build a workflow and UI etc, but again exposes you to risk if nefarious types get access to the channel or the links sent to it.
Depends on your appetite for risk I guess.
another user performs signing action on your local system? and you are sly?
there is no way to protect their password.
use two factor authentication.
The way this would normally be handled is for the user to request an action. This (unsigned) action-request is recorded in the database. The admin user is able to see this unsigned request in their account, and make an (authenticated) request to sign it. The user would be able to see the status of their request, and whether it has been signed yet.

Profile completion after e-mail verification

I'm building a web application for two different types of users, with a different registration form for each of them. I could split up those forms and send a verification e-mail after the form is validated.
But I'd prefer to have one general small form where the user enters his/her e-mail address and user type. The server then sends a verification e-mail with a link to further complete the profile, depending on the chosen user type.
Now my question is: should I include a password field in the small registration form? I have seen it before on many websites, but I can't see why I would include it. My plan is to make the user choose his/her password on profile completion. Nothing about the user will be stored until he/she completes the profile (I would securely hash the e-mail address with a timestamp in a url).
In general, the developers ask all the details including password at the time of registration and they allow to login using the same password. However, there is an open risk of unverified user can access all or some of the feature of the application. Sometimes the application also provides time frame of 24-72 hours to activate the user account, within this period user can access account with some restrictions.
For sensitive applications, you can ask for the password once the user verify the email address. So, that you are assured about the verified user.
If you are providing the feature to access the user accounts without being verified, make sure that the unverified account users can access the account with restrictions according to your application context.

How does account validation work?

Usually when you create an account to some webpage they send you an email with a link in order for you to validate your account.
If you click that link then you account is validated and thats the end of it.
How does this work?
Is that url unique for every new user so they know who visited what?
This is not a web service related question, however I can conceptually guide your through what you need to do.
When a user registers their information will probably be captured into some user table in a database somewhere. This user is marked as pending. The system can then generate a unique id i.e. a GUID which is stored next to the user entry in the database. This GUID if properly constructed will be impossible to guess. This GUID is then added as a GET parameter to the URL that you in an email to the user.
For example you might have the URL:
http://example.com/activateuser?confirmuid=5e706449-2cbf-4938-8109-fb564c196d8f
Thus every user will use the same URL with different confirmuid parameter. This URL will then post the confirmuid to the page where you can then use this value to look up the user in the database and then active the user or move it from a pending state to an active state.
Simple right.

Auto authentication through email link

I have written an agent which takes the username and authenticate user, if authentication is successful then it redirects to the actual URL of the database.
For taking name of the user, I am using #Formulas. Hence, I can use my method of authentication in any link or hotspot or button in Notes Client. But, I face problem to send this method through reminder email links.
When I create a URL through backend agent, this URL/hotspot should have my code with #formula. In simple words, I want to pass #Dblookup inside URL/hotspot through my email link. How to accomplish this task ?
Or is there any alternative to get user name if any person clicks a link in his email ?
Only Notes client has to be used.
Edit#1: Adding scenario for better explanation:
Our users are not happy to re-authenticate themselves for web applications. So, we have been trying something like if they want to open a webdoclink, which they got through their email in notes client, so they shouldn't be asked to authenticate again (since they have already logged into notes client).
We could achieve this for static application links, where application name is not changed. Now, the challenge we are facing is how to do it for reminder emails, which have links to particular web document (links here are not static. They are differed by unique document ids).
For this to work, we need shortname of person who clicked that link from his email.
You probably need to be sending an Action hotspot instead of a URL hotspot; but it is very difficult to guess without seeing what your code is really doing. Also, I believe that creating an Action hotspot probably will require copying it from a previously saved rich text field, perhaps in a profile document and appending it to the rich text body field of the message you are sending. (That's a technique I've used in the past to create action hotspots, anyhow. I'm not sure if there are better alternatives.)
And since this is for Notes client recipients, the other technique that I would probably explore is the use of a store-form-in-document message instead of an ordinary email message. That way you just need to have a button containing the #DbLookup on the form that you send in the message.
I agree with leyer. The ACL (Access Control List) is the main tool to use to decide functionality. For instance a user can have access to the db. Then you can define who can create databases, create emails. It is best to use the ACL so you can also use Roles and other tools. Basic LotusScript can access the ACL on open events or do a test in buttons.
Regarding the scenario you are describing, if the issue is that users have to re-authenticate for every web application on the server, you would be better of implementing SSO/Session based authentication on the server then coding this workaround. With Session based authentication, users only have to authenticate once.
From the admin help:
Session-based name-and-password authentication sends the client's name and unencrypted password, and is sent with each request to the server. Session-based authentication differs in that the user's name and password information is sent over the network only the first time the user logs in to a server, not each time a request is posted. After login, the user's name and logon information is stored in a cookie in the user's browswer, and the browser sends the cookie to the server with each request. Before honoring a request, the server verifies the information in the cookie and uses the cookie contents to identify the logged-in user. The session is only valid within the browser in which the login was performed. If the user shuts down the browser in which the session login took place, the user's session will be ended and the cookie will be destroyed.
Using session-based name-and-password authentication provides greater control over user interaction than basic name-and-password authentication. For example, you can customize the form in which users enter their name and password information. It also allows users to log out of the session without closing the browser.
If you are using windows based servers, you could even implement SPNEGO, automatically signing the users in using der Windows account, therefore eliminating login prompts completely.
With Domino 9, you also have the option of using Security Assertion Markup Language (SAML) to configure federated-identity authentication.
In your case, I would start with Session-based name-and-password authentication to solve the multiple-login issue.

Resources