Google Authenticator Multi-part (TOTP) login implementation for CakePHP - cakephp

I am looking to implement Google Authenticator into a CakePHP application. The trick is that a user can determine whether or not they want to use it. This means that if a user is using the multi-part login, they will log in normally with their username and password. Once they have successfully submitted their correct username / password combination, they need to be redirected to the page that asks for their passcode from Google Authenticator.
How do you limit the Authentication success until AFTER they enter the passcode? I can do the redirect and everything just fine, but if they exit the passcode form and go to the site, they have already authenticated using their username / password and they can navigate through the site just fine.
I need some direction on how to shut down authentication until AFTER the passcode confirmation is successful. Any ideas?

I noticed this question is pretty old and unanswered, I also work on something similar so I'll share my two cents. Hope you've already solved this problem by now.
Your user management system should provide a session key only after the entire login process was fulfilled, this means that you should let users in only after they provide all auth data through all steps.
receive user and password
check credentials and authentication options
if credentials are ok and no Google Auth enabled, give him session key, else retry
if credetials are ok and Google Auth enabled, pass $_POST['user'] to challenge form
if TOTP password matches server-side check, return session key, else retry
$_POST[] ----> loginCheck() ----> if(GAuth) ----> checkTotp() ----> sessionKey
| |
*---------------------------------*
loginCheck() should check if user and passwords are ok, otherwise deny access
if(GAuth) should return true or false, depeding if your user uses GAuth
checkTotp should be a method to check TOTP password on client and server
sessionKey should be the token used to access protected content, stored server-side and client-side for a period of time
Or adapt this idea to your needs ... in my opinion you should accept the user in the system when he passes all authentication trials.
You could make an user form that hols user/password and passcode and process all data at once and avoid two pages.
Read more about https://www.rfc-editor.org/rfc/rfc6238

Related

Using Firebase Auth for my react web app. Problems regarding account creation happening before sendEmailVerification and isEmailedVerified = true

I used firebase auth email/password sign in with the isEmailVerified property. isEmailVerified set to true allows the user to get through to their logged in home page. isEmailVerified set to false displays a screen telling the user to verify their email before they can get through. Two problems here:
If a user creates an account with an email that is not theirs (I know email link sign up solves this, but looking for a solution via the email/password auth route), is there a way to discard of that account when the user doesn't verify their email within a certain amount of time? Trying to avoid excess false/mistake accounts.
Lets say the user does use a correct email to sign up and they are through to their account after email verification, but they want to change their email at a later date (say via account settings using the updateEmail method, for example), then the user changing their email to an incorrect email would essentially make the user lose their account. This is similar to problem #1, but worse, because in problem #1, some sort of solution that discards accounts with isEmailedVerified = false would discard an brand new account with no history, BUT with this problem, that same solution would discard a used account with history attached to it. This is because the user would then have to login with the new incorrect email on their account, but isEmailVerified would be set to false, but they can never correct it since they don't have access to the new email.
These 2 problems happen because in firebase auth accounts are created before the sendEmailVerification is sent and isEmailVerified is set to true. Any solution?
I know email link sign up solves problem #1 since account creation and email verification happens together on initial sign up, but looking for a solution via the email/password route. I don't think email link sign up solves problem #2.
You can have a function that checks your users list periodically and finds & removes users whose account has not been approved yet (after x days)
// running periodically & using firebase admin SDK
getAuth()
.getUser(uid)
.then((userRecord) => {
console.log(userRecord)
// if email is not verified & sign up date > x => delete user
})
.catch((error) => {
console.log('Error fetching user data:', error);
});
Here user Record will contain information about user's email verification.
Problem 2. You should allow another sign in method, i.e., phone, etc. so that if they lose the email, they can still verify their identify in another way. Otherwise your issue is a logical issue.
But if you want to keep it with just email, then you should not update their email right away, rather send verification and on the verification process you would also update their email. The logic needs to be handled in the backend.

How should I store OAuth with my own authentication system?

I have an existing signup/login system: a user enters an email and password. The password is hashed. I store it in a database.
When a user logs in, they entire their email and password. The password is hashed, and I look up the email in the database and check that the email matches. If it does, they are logged in.
I want to add a system to let users login with a 3rd party OAuth, such as GitHub. I have that setup, but I am unsure what data to store in my database.
I was thinking I take their GitHub email as the email and then use the access token for their GitHub as the password (so I would hash it and store it.)
I think this would work, but I am worried that the access tokens could change meaning they would be locked out of their account.
If I shouldn't be using the access token as a password, what should I be using? I need to store the user's email on my database but that requires a password currently, which I can't get if they use GitHub login.
(Note that when the user logs in, I call my backend to generate an access token (JWT) which I can use to require their user details and then store it in local storage. I'd like to then be able to do the same thing with with GitHub or whatever.)
oAuth is usually for authorization. Meaning, you get an access token from the authorization server, the resource server validates it and let the user access to the data.
In your case, you "do not really need" the access token - you want to use oAuth just for the authentication. Web-applications (like StackOverflow) do this to "save the trouble" of handling the authentication flows. Meaning, if I write a secured application, I need to implement somehow the create account flow, login flow, forgot password, etc. When you use a 3rd-party authentication, you save this trouble.
However, your application does need some user-id to perform actions; so you must create a user-id in you app when a user appears for the first time. Since then, you do not need to worry about password-expiry, forgotten-password and even not for the login. When the user logs-in, you get the access token and all you need to do is to get yours app' user-id from it.
Thus, I do not see a reason why you need to store a 'password', or the access token.
Hope that makes sense.
What you are looking for is actually OpenID Connect - it's an authentication framework built on top of OAuth, which lets you log in users using external Identity Providers, like Github.
When a user logs in using GitHub then you will receive an id_token in a form of a signed JWT. You can easily verify the authenticity of the JWT - so you can easily make sure that the id token really comes from Github and presents real data. Usually one of the information in the id token will be the user's email. You can use that to look up the user in your database. You don't need any password in this case.
So, you will have two ways of finding a user in your DB - either through comparing the email and password, or by looking up the user's email from a validated id token from Github.

Concurrent login with identity server4

Want to logout from all other session(s) when user logs in other browser.
I am able to delete the PersistedGrants but cookies are still present.
When user refreshes the page a new access_token is generated due to refresh_token.
So basically we want only one concurrent session of user.
Any help would be appreciated.
By default IdSrv persists user session in a cookie. You can change that by implementing IUserSession and registering in DI. Doing so you get access to logged in clients within one session. Having that knowledge, you can register your custom middleware with the check: when authenticated, i.e. has auth cookie, and no other session for the same user id then ok, else handle the collision: the one who logged in earlier logs out. Just an idea, but should work. See my customization of the DefaultUserSession - backing it to Redis, used for another purpose, but should be enough to demonstrate the approach.

auth0 does not require password after logout; logs back in without password

I've been learning Auth0 for a React / React Native project. With two different apps now, including one from their site, I see the following behavior:
clear browser cache
login
enter password, now logged in
select logout
--> now logged out
select login
am NOT prompted for password again, just logged in without interaction.
It seems the session has been kept alive even though I logged out. I would expect that if I manually log out of an application, I must re-authorize with my password on the next login attempt.
As I said I've seen this twice now, once with my own project and once with the tutorial they provide at https://auth0.com/blog/react-tutorial-building-and-securing-your-first-app/ . Doesn't make any sense to me. Am I missing something?
Thanks ~~
This is the Seamless SSO behaviour explained here. This is now enabled by default on all tenants and it "seamlessly" logs the user in without showing any prompts if a session exists for the user in the Authorization server (Auth0 in this case). Previously you would get a prompt that said "Last time you logged in with ..." Clicking it would login you in without requiring a password.
If you are "Logging out" and yet you can log back in again without needing to enter credentials, the most likely explanation is that you are actually not calling the https://YOUR_AUTH0_DOMAIN/v2/logout endpoint which logs out the user by clearing their SSO cookie in Auth0. You can confirm this endpoint is called from Network tab in your browser when you click to logout.
The Auth0 React quickstart by default does not call the logout endpoint, it only removes the tokens from browser storage. To clear the SSO cookie and logout from IdP using Auth0.js you need to call the logout function as well. Refer to the Auth0.js logout function here.
Hope that helps.

active directory ldap login auth when password needs changing

Let me explain my issue.
I have a PHP application using an LDAP connection to an Active Directory server to authenticate. If i make it so that a user needs to change their password at the next login it won't allow me to authenticate them before i allow the password change. I can detect that the password change is required but if i allowed the user to change it then i have no way to work out that the user is valid or not, which means that the system could be hacked by just knowing the username of a user that's password as expired.
This to me seems daft... is there something im missing..
Currently I am
binding to the server
checking if the password as expired or not
checking the authentication users details
This is what I get returned if the users account is set to change password on next login, auth as failed but there is a password change request.
Is there a specific order the requests need to be sent so i can auth the user before the password change it sent?
Thanks in advance
By marking the account as Must change password at next login there is effectively no password to authenticate so this doesn't translate to the web.
A better option is to compare the users' pwdLastSet attribute against the domain policy and enforce the change in the application not in AD.

Resources